Testing med Google Truth

1. Oversikt

Sannhet er en flytende og fleksibelt rammeverk for åpen kildekode-testing designet for å gjøre testpåstander og feilmeldinger mer lesbare.

I denne artikkelen vil vi utforske de viktigste funksjonene i Sannhet rammeverk og implementer eksempler for å vise evner.

2. Maven-avhengigheter

Først må vi legge til sannhet og sannhet-java8-utvidelse til vår pom.xml:

 com.google.truth sannhet 0.32 com.google.truth.extensions sannhet-java8-utvidelse 0.32 test 

Du finner de nyeste versjonene av sannhet og sannhet-java8-utvidelse på Maven Central.

3. Introduksjon

Sannhet tillater oss å skrive lesbare påstander og feilmeldinger for en rekke klasser:

  • Standard Java - primitiver, matriser, strenger, gjenstander, samlinger, kastekasser, klasser osv.
  • Java 8Valgfri og Strøm tilfeller
  • GuavaValgfri, Multikart, Multisett, og Bord gjenstander
  • Egendefinerte typer - ved å utvide Emne klasse, som vi får se senere

Gjennom Sannhet og Sannhet 8 klasser, gir biblioteket verktøy for å skrive påstander som fungerer på en Emne, det er verdien eller objektet som testes.

Når motivet er kjent, Sannhet kan resonnere ved kompileringstid om hvilke forslag som er kjent for det emnet. Dette gjør det mulig å returnere innpakninger rundt vår verdi som erklærer forslagsmetoder som er spesifikke for det aktuelle emnet.

For eksempel når du hevder på en liste, Sannhet returnerer en IterableSubject eksempel definere metoder som inneholder () og inneholderAnyOf (), blant andre. Når du hevder på en Kart, det returnerer a MapSubject som erklærer metoder som inneholderEntry () og inneholderKey ().

4. Komme i gang

La oss først importere for å begynne å skrive påstander SannhetInngangspunkter:

importer statisk com.google.common.truth.Truth. *; importer statisk com.google.common.truth.Truth8. *;

La oss nå skrive en enkel klasse som vi vil bruke i noen av eksemplene som følger:

public class User {private String name = "John Doe"; private List emails = Arrays.asList ("[email protected]", "[email protected]"); offentlig boolsk er lik (Object obj) {if (obj == null || getClass ()! = obj.getClass ()) {return false; } Bruker annen = (Bruker) obj; returner Objects.equals (dette.navn, annet.navn); } // standardkonstruktører, getters og setters}

Legg merke til skikken er lik() metode, der vi oppgir at to Bruker objekter er like hvis navnene er.

5. Standard Java-påstander

I denne delen vil vi se detaljerte eksempler på hvordan du skriver testpåstander for standard Java-typer.

5.1. Gjenstand Påstander

Sannhet gir den Emne innpakning for å utføre påstander om objekter. Emne er også overordnet til alle andre innpakninger i biblioteket og erklærer metoder for å bestemme om en Gjenstand, i vårt tilfelle a Bruker, er lik et annet objekt:

@Test offentlig ugyldig nårComparingUsers_thenEqual () {User aUser = new User ("John Doe"); Bruker anotherUser = ny bruker ("John Doe"); assertThat (aUser) .isEqualTo (anotherUser); }

eller hvis det er lik et gitt objekt i en liste:

@Test offentlig ugyldig nårComparingUser_thenInList () {User aUser = new User (); assertThat (aUser) .isIn (Arrays.asList (1, 3, aUser, null)); }

eller hvis det ikke er:

@Test offentlig ugyldig nårComparingUser_thenNotInList () {// ... assertThat (aUser) .isNotIn (Arrays.asList (1, 3, "Three")); }

hvis det er null eller ikke:

@Test offentlig ugyldig nårComparingUser_thenIsNull () {User aUser = null; assertThat (aUser) .isNull (); } @Test offentlig ugyldig nårComparingUser_thenNotNull () {User aUser = new User (); assertThat (aUser) .isNotNull (); }

eller hvis det er en forekomst av en bestemt klasse:

@Test offentlig ugyldig nårComparingUser_thenInstanceOf () {// ... assertThat (aUser) .isInstanceOf (User.class); }

Det er andre påstandsmetoder i Emne klasse. For å oppdage dem alle, se Emne dokumentasjon.

I de følgende avsnittene, vi skal fokusere på de mest relevante metodene for hver spesifikke typeSannhet støtter. Husk imidlertid at alle metoder i Emne klasse kan også brukes.

5.2. Heltall, Flyte, og Dobbelt Påstander

Heltall, Flyte, og Dobbelt tilfeller kan sammenlignes for likestilling:

@Test offentlig ugyldig nårComparingInteger_thenEqual () {int anInt = 10; assertThat (anInt) .isEqualTo (10); }

hvis de er større:

@Test offentlig ugyldig nårComparingFloat_thenIsBigger () {float aFloat = 10.0f; hevder at (aFloat) .isGreaterThan (1.0f); }

eller mindre:

@Test offentlig ugyldig nårComparingDouble_thenIsSmaller () {double aDouble = 10.0f; assertThat (aDouble) .isLessThan (20.0); }

Dessuten, Flyte og Dobbelt Forekomster kan også sjekkes for å se om de er innenfor en forventet presisjon eller ikke:

@Test offentlig ugyldig nårComparingDouble_thenWithinPrecision () {doble aDouble = 22.18; hevder at (aDobbelt) .is innenfor (2) .av (23d); } @Test offentlig ugyldig nårComparingFloat_thenNotWithinPrecision () {float aFloat = 23.04f; hevder at (aFloat) .isNotWithin (1.3f) .of (100f); }

5.3. BigDecimal Påstander

Foruten de vanlige påstandene, kan denne typen sammenlignes uten å se på skalaen:

@Test offentlig ugyldig nårComparingBigDecimal_thenEqualIgnoringScale () {BigDecimal aBigDecimal = BigDecimal.valueOf (1000, 3); assertThat (aBigDecimal) .isEqualToIgnoringScale (ny BigDecimal (1.0)); }

5.4. Boolsk Påstander

Bare to relevante metoder er gitt, er sant() og isFalse ():

@Test offentlig ugyldig nårCheckingBoolean_thenTrue () {boolean aBoolean = true; assertThat (aBoolean) .isTrue (); }

5.5. String Påstander

Vi kan teste om en String starter med en bestemt tekst:

@Test offentlig ugyldig nårCheckingString_thenStartsWith () {String aString = "Dette er en streng"; assertThat (aString) .startsWith ("This"); }

I tillegg kan vi sjekke om strengen inneholder en gitt streng, om den ender med en forventet verdi, eller om den er tom. Testtilfeller for disse og andre metoder er tilgjengelige i kildekoden.

5.6. Array påstander

Vi kan sjekke Arrays for å se om de er lik andre matriser:

@Test offentlig ugyldig nårComparingArrays_thenEqual () {String [] firstArrayOfStrings = {"one", "two", "three"}; String [] secondArrayOfStrings = {"one", "two", "three"}; assertThat (firstArrayOfStrings) .isEqualTo (secondArrayOfStrings); }

eller hvis de er tomme:

@Test offentlig ugyldig nårCheckingArray_thenEmpty () {Object [] anArray = {}; assertThat (anArray) .isEmpty (); }

5.7. Sammenlignelig Påstander

Foruten å teste om en Sammenlignelig er større enn eller mindre enn en annen forekomst, kan vi sjekke om de minst har en gitt verdi:

@Test offentlig ugyldig nårCheckingComparable_thenAtLeast () {Comparable aComparable = 5; hevder at (aComparable) .isAtLeast (1); }

Vi kan også teste om de er innenfor et bestemt område:

@Test offentlig ugyldig nårCheckingComparable_thenInRange () {// ... assertThat (aComparable) .isIn (Range.closed (1, 10)); }

eller i en bestemt liste:

@Test offentlig ugyldig nårCheckingComparable_thenInList () {// ... assertThat (aComparable) .isIn (Arrays.asList (4, 5, 6)); }

Vi kan også teste om to Sammenlignelig tilfeller er likeverdige i henhold til klassens sammenligne med() metode.

La oss først endre vår Bruker klasse for å implementere Sammenlignelig grensesnitt:

offentlig klasse Brukerverktøy Sammenlignbar {// ... offentlig int CompareTo (bruker o) {returner this.getName (). CompareToIgnoreCase (o.getName ()); }}

La oss nå hevde at to brukere med samme navn er ekvivalente:

@Test offentlig ugyldig nårComparingUsers_thenEquivalent () {User aUser = new User (); aUser.setName ("John Doe"); Bruker anotherUser = ny bruker (); anotherUser.setName ("john doe"); assertThat (aUser) .isEquivalentAccordingToCompareTo (anotherUser); }

5.8. Iterabel Påstander

I tillegg til å hevde størrelsen på en Iterabel for eksempel om det er tomt eller ikke har duplikater, mest typiske påstander om et Iterabel er at den inneholder noe element:

@Test offentlig ugyldig nårCheckingIterable_thenContains () {List aList = Arrays.asList (4, 5, 6); assertThat (aList) .contains (5); }

at den inneholder ethvert element av et annet Iterabel:

@Test offentlig ugyldig nårCheckingIterable_thenContainsAnyInList () {List aList = Arrays.asList (1, 2, 3); assertThat (aList) .containsAnyIn (Arrays.asList (1, 5, 10)); }

og at motivet har de samme elementene, i samme rekkefølge, som en annen:

@Test offentlig ugyldig nårCheckingIterable_thenContainsExactElements () {List aList = Arrays.asList ("10", "20", "30"); List anotherList = Arrays.asList ("10", "20", "30"); assertThat (aList) .containsExactlyElementsIn (anotherList) .inOrder (); }

og hvis den bestilles med en tilpasset komparator:

@Test offentlig ugyldig gittComparator_whenCheckingIterable_thenOrdered () {Comparator aComparator = (a, b) -> new Float (a) .compareTo (new Float (b)); Liste aList = Arrays.asList ("1", "012", "0020", "100"); assertThat (aList) .isBestilt (aComparator); }

5.9. Kart Påstander

I tillegg til å hevde at en Kart forekomst er tom eller ikke, eller har en bestemt størrelse; vi kan sjekke om den har en spesifikk oppføring:

@Test offentlig ugyldig nårCheckingMap_thenContainsEntry () {Map aMap = new HashMap (); aMap.put ("en", 1L); assertThat (aMap) .containsEntry ("one", 1L); }

hvis den har en bestemt nøkkel:

@Test offentlig ugyldig nårCheckingMap_thenContainsKey () {// ... assertThat (map) .containsKey ("one"); }

eller hvis den har de samme oppføringene som en annen Kart:

@Test offentlig ugyldig nårCheckingMap_thenContainsEntries () {Map aMap = new HashMap (); aMap.put ("første", 1L); aMap.put ("andre", 2.0); aMap.put ("tredje", 3f); Kartlegg en annenMap = ny HashMap (aMap); assertThat (aMap) .containsExactlyEntriesIn (anotherMap); }

5.10. Unntak Påstander

Det er kun gitt to viktige metoder Unntak gjenstander.

Vi kan skrive påstander adressert til årsaken til unntaket:

@Test offentlig ugyldig nårCheckingException_thenInstanceOf () {Exception anException = new IllegalArgumentException (new NumberFormatException ()); assertThat (anException) .hasCauseThat () .isInstanceOf (NumberFormatException.class); }

eller til budskapet:

@Test offentlig ugyldig nårCheckingException_thenCauseMessageIsKnown () {Unntak anException = ny IllegalArgumentException ("Dårlig verdi"); assertThat (anException) .hasMessageThat () .startsWith ("Bad"); }

5.11. Klasse Påstander

Det er bare en viktig metode for Klasse påstander som vi kan teste om en klasse kan tildeles til en annen:

@Test offentlig ugyldig nårCheckingClass_thenIsAssignable () {Class aClass = Double.class; assertThat (aClass) .isAssignableTo (Number.class); }

6. Java 8 påstander

Valgfri og Strøm er de eneste to Java 8-typene som Sannhet støtter.

6.1. Valgfri Påstander

Det er tre viktige metoder for å verifisere en Valgfri.

Vi kan teste om det har en bestemt verdi:

@Test public void whenCheckingJavaOptional_thenHasValue () {Optional anOptional = Optional.of (1); hevder at (en valgfri) .har verdi (1); }

hvis verdien er til stede:

@Test public void whenCheckingJavaOptional_thenPresent () {Optional anOptional = Optional.of ("Baeldung"); assertThat (anOptional) .isPresent (); }

eller hvis verdien ikke er til stede:

@Test offentlig ugyldig nårCheckingJavaOptional_thenEmpty () {Valgfritt anOptional = Optional.empty (); assertThat (an Valgfritt) .isEmpty (); }

6.2. Strøm Påstander

Påstander om en Strøm er veldig lik de for en Iterabel.

For eksempel kan vi teste om en bestemt Strøm inneholder alle gjenstander av et Iterabel i samme rekkefølge:

@Test offentlig ugyldig nårCheckingStream_thenContainsInOrder () {Stream anStream = Stream.of (1, 2, 3); assertThat (anStream) .containsAllOf (1, 2, 3) .inOrder (); }

For flere eksempler, se Iterabel Påstander.

7. Guava-påstander

I denne delen ser vi eksempler på påstander om de støttede Guava-typene i Sannhet.

7.1. Valgfri Påstander

Det er også tre viktige påstandsmetoder for en Guava Valgfri. De hasValue () og er tilstede() metoder oppfører seg nøyaktig som med en Java 8 Valgfri.

Men i stedet for er tom() å hevde at en Valgfri ikke er til stede, bruker vi er fraværende():

@Test offentlig ugyldig nårCheckingGuavaOptional_thenIsAbsent () {Valgfritt anOptional = Optional.absent (); assertThat (anOptional) .isAbsent (); }

7.2. Multikart Påstander

Multikart og standard Kart påstander er veldig like.

En bemerkelsesverdig forskjell er at vi kan få flere verdier av en nøkkel i en Multikart og komme med påstander om disse verdiene.

Her er et eksempel som tester om verdiene til “en” -tasten har størrelsen to:

@Test offentlig ugyldig nårCheckingGuavaMultimap_thenExpectedSize () {Multimap aMultimap = ArrayListMultimap.create (); aMultimap.put ("en", 1L); aMultimap.put ("en", 2.0); assertThat (aMultimap) .valuesForKey ("one") .hasSize (2); }

For flere eksempler, se Kart Påstander.

7.3. Multisett Påstander

Påstander for Multisett objekter inkluderer de for en Iterabel og en ekstra metode for å verifisere om en nøkkel har et bestemt antall forekomster:

@Test offentlig ugyldig nårCheckingGuavaMultiset_thenExpectedCount () {TreeMultiset aMultiset = TreeMultiset.create (); aMultiset.add ("baeldung", 10); assertThat (aMultiset) .hasCount ("baeldung", 10); }

7.4. Bord Påstander

I tillegg til å kontrollere størrelsen eller hvor den er tom, kan vi sjekke a Bord for å verifisere om den inneholder en bestemt kartlegging for en gitt rad og kolonne:

@Test offentlig ugyldig nårCheckingGuavaTable_thenContains () {Table aTable = TreeBasedTable.create (); aTable.put ("firstRow", "firstColumn", "baeldung"); assertThat (aTable) .contains ("firstRow", "firstColumn"); }

eller hvis den inneholder en bestemt celle:

@Test offentlig ugyldig nårCheckingGuavaTable_thenContainsCell () {Table aTable = getDummyGuavaTable (); assertThat (aTable) .containsCell ("firstRow", "firstColumn", "baeldung"); }

Videre kan vi sjekke om den inneholder en gitt rad, kolonne eller verdi. Se kildekoden for de aktuelle testtilfellene.

8. Egendefinerte feilmeldinger og etiketter

Når en påstand mislykkes, Sannhet viser veldig lesbare meldinger som angir nøyaktig hva som gikk galt. Noen ganger er det imidlertid nødvendig å legge til mer informasjon i disse meldingene for å gi mer informasjon om hva som skjedde.

Sannhet lar oss tilpasse disse feilmeldingene:

@Test offentlig ugyldig nårFailingAssertion_thenCustomMessage () {assertWithMessage ("TEST-985: Secret user subject was NOT null!") .That (new User ()) .isNull (); }

Etter å ha kjørt testen får vi følgende utdata:

TEST-985: Hemmelig brukeremne var IKKE null !: Ikke sant at <[e-postbeskyttet]> er null

Vi kan også legge til en egendefinert etikett som vises før emnet vårt i feilmeldinger. Dette kan være nyttig når et objekt ikke har en nyttig strengrepresentasjon:

@Test offentlig ugyldig nårFailingAssertion_thenMessagePrefix () {User aUser = new User (); assertThat (aUser) .named ("User [% s]", aUser.getName ()) .isNull (); }

Hvis vi kjører testen, kan vi se følgende utdata:

Ikke sant at bruker [John Doe] (<[email protected]>) er null

9. Utvidelser

Forlenger Sannhet betyr at vi kan legge til støtte for tilpassede typer. For å gjøre dette må vi lage en klasse som:

  • utvider Emne klasse eller en av dens underklasser
  • definerer en konstruktør som godtar to argumenter - a Feilstrategi og en forekomst av vår tilpassede type
  • erklærer et felt av SubjectFactory type, hvilken Sannhet vil bruke til å lage forekomster av vårt tilpassede emne
  • implementerer en statisk hevder at () metode som godtar vår tilpassede type
  • avslører API for testpåstand

Nå som vi vet hvordan vi skal utvide Sannhet, la oss lage en klasse som legger til støtte for objekter av typen Bruker:

offentlig klasse UserSubject utvider ComparableSubject {private UserSubject (FailureStrategy failureStrategy, User target) {super (failureStrategy, target); } privat statisk endelig SubjectFactory USER_SUBJECT_FACTORY = ny SubjectFactory () {public UserSubject getSubject (FailureStrategy failureStrategy, User target) {return new UserSubject (failureStrategy, target); }}; offentlig statisk UserSubject assertThat (User user) {return Truth.assertAbout (USER_SUBJECT_FACTORY) .that (user); } public void hasName (String name) {if (! actual (). getName (). equals (name)) {fail ("has name", name); }} public void hasNameIgnoringCase (Strengnavn) {if (! actual (). getName (). equalsIgnoreCase (name)) {fail ("has name ignoring case", name); }} offentlige IterableSubject-e-poster () {returner Truth.assertThat (faktisk (). getEmails ()); }}

Nå kan vi importere statisk hevder at () metode for vårt tilpassede emne og skriv noen tester:

@Test offentlig ugyldig nårCheckingUser_thenHasName () {User aUser = new User (); assertThat (aUser) .hasName ("John Doe"); } @Test offentlig ugyldig nårCheckingUser_thenHasNameIgnoringCase () {// ... assertThat (aUser) .hasNameIgnoringCase ("john doe"); } @Test offentlig ugyldig givenUser_whenCheckingEmails_thenExpectedSize () {// ... assertThat (aUser) .emails () .hasSize (2); }

10. Konklusjon

I denne opplæringen undersøkte vi mulighetene Sannhet gir oss å skrive mer lesbare tester og feilmeldinger.

Vi viste frem de mest populære påstandsmetodene for støttede Java- og Guava-typer, tilpassede feilmeldinger og utvidet Sannhet med tilpassede fag.

Som alltid kan fullstendig kildekode for denne artikkelen finnes på Github.


$config[zx-auto] not found$config[zx-overlay] not found