Testiranje s Hamcrestom
1. Pregled
Hamcrest je dobro poznati okvir koji se koristi za jedinstveno testiranje u Java ekosustavu. Sadržan je u JUnit-u i, jednostavno rečeno, koristi postojeće predikate - nazvane klase podudaranja - za donošenje tvrdnji.
U ovom uputstvu hoćemo istražiti Hamcrest API i naučite kako to iskoristiti za pisanje urednijih i intuitivnijih jediničnih testova za naš softver.
2. Hamcrest postavljanje
Možemo koristiti Hamcrest s maven dodavanjem sljedeće ovisnosti našem pom.xml datoteka:
org.hamcrest hamcrest-svi 1.3
Najnoviju verziju ove knjižnice uvijek možete pronaći ovdje.
3. Primjer testa
Hamcrest se obično koristi sa junit i drugi ispitni okviri za iznošenje tvrdnji. Točnije, umjesto korištenja junit‘Je mnogobrojna tvrditi metode, koristimo samo API-jev single ustvrdiTo izjava s odgovarajućim podudaranjima.
Pogledajmo primjer koji testira dva Nizs za jednakost bez obzira na slučaj. To bi nam trebalo dati jasnu predodžbu o tome kako Hamcrest uklapa se u metodu ispitivanja:
javna klasa StringMatcherTest {@Test javna praznina given2Strings_whenEqual_thenCorrect () {String a = "foo"; Niz b = "FOO"; assertThat (a, jednakToIgnoringCase (b)); }}
U sljedećim odjeljcima ćemo pogledati nekoliko drugih uobičajenih podudaranja Hamcrest ponude.
4. The Objekt Podudaranje
Hamcrest pruža podudaranje za iznošenje tvrdnji o proizvoljnim Java objektima.
Tvrditi da je toString metoda an Objekt vraća navedeni Niz:
@Test javna praznina givenBean_whenToStringReturnsRequiredString_thenCorrect () {Osoba osoba = nova osoba ("Baraka", "Washington"); Niz str = person.toString (); assertThat (osoba, hasToString (str)); }
Također možemo provjeriti je li jedan razred podklase drugog:
@Test javna praznina given2Classes_whenOneInheritsFromOther_thenCorrect () {assertThat (Cat.class, typeCompatibleWith (Animal.class)); }}
5. Podudaranje graha
Možemo koristiti Hamcrest'S Bean Matcher za pregled svojstava Java graha.
Pretpostavimo sljedeće Osoba grah:
javni razred Osoba {Ime niza; Adresa niza; javna osoba (niz personName, string personAddress) {name = personName; adresa = personAddress; }}
Možemo provjeriti ima li grah svojstvo, Ime ovako:
@Test javna praznina givenBean_whenHasValue_thenCorrect () {Osoba osoba = nova osoba ("Baeldung", 25); assertThat (person, hasProperty ("name")); }
Također možemo provjeriti je li Osoba ima adresa svojstvo, inicijalizirano u New Yorku:
@Test javna praznina givenBean_whenHasCorrectValue_thenCorrect () {Osoba osoba = nova osoba ("Baeldung", "New York"); assertThat (person, hasProperty ("address", jednakTo ("New York"))); }
Možemo provjeriti i dvije Osoba objekti se grade s istim vrijednostima:
@Test javna praznina given2Beans_whenHavingSameValues_thenCorrect () {Person person1 = new Person ("Baeldung", "New York"); Osoba person2 = nova osoba ("Baeldung", "New York"); assertThat (person1, samePropertyValuesAs (person2)); }
6. The Kolekcija Podudaranje
Hamcrest osigurava podudarnosti za inspekciju Kolekcijas.
Jednostavna provjera da biste saznali je li Kolekcija prazno je:
@Test javna praznina givenCollection_whenEmpty_thenCorrect () {List emptyList = new ArrayList (); assertThat (emptyList, empty ()); }
Da biste provjerili veličinu a Kolekcija:
@Test javna praznina danaAList_whenChecksSize_thenCorrect () {Popis hamcrestMatchers = Arrays.asList ("zbirke", "grah", "tekst", "broj"); assertThat (hamcrestMatchers, hasSize (4)); }
Također ga možemo koristiti za utvrđivanje da niz ima potrebnu veličinu:
@Test javna praznina givenArray_whenChecksSize_thenCorrect () {String [] hamcrestMatchers = {"zbirke", "grah", "tekst", "broj"}; assertThat (hamcrestMatchers, arrayWithSize (4)); }
Da biste provjerili je li Kolekcija sadrži dane članove, bez obzira na redoslijed:
@Test javna praznina danaAListAndValues_whenChecksListForGivenValues_thenCorrect () {Popis hamcrestMatchers = Arrays.asList ("zbirke", "grah", "tekst", "broj"); assertThat (hamcrestMatchers, containsInAnyOrder ("grah", "tekst", "zbirke", "broj")); }
Da bi se dalje ustvrdilo da je Kolekcija članovi su poredani prema redoslijedu:
@Test javna praznina danaAListAndValues_whenChecksListForGivenValuesWithOrder_thenCorrect () {Popis hamcrestMatchers = Arrays.asList ("zbirke", "grah", "tekst", "broj"); assertThat (hamcrestMatchers, sadrži ("zbirke", "grah", "tekst", "broj")); }
Da biste provjerili ima li niz jedan zadani element:
@Test javna praznina givenArrayAndValue_whenValueFoundInArray_thenCorrect () {String [] hamcrestMatchers = {"zbirke", "grah", "tekst", "broj"}; assertThat (hamcrestMatchers, hasItemInArray ("tekst")); }
Za isti test možemo koristiti i alternativno podudaranje:
@Test javna praznina givenValueAndArray_whenValueIsOneOfArrayElements_thenCorrect () {String [] hamcrestMatchers = {"zbirke", "grah", "tekst", "broj"}; assertThat ("tekst", isOneOf (hamcrestMatchers)); }
Ili još uvijek možemo učiniti isto s drugim podudaranjem, poput ovako:
@Test javna praznina givenValueAndArray_whenValueFoundInArray_thenCorrect () {String [] niz = novi String [] {"zbirke", "grah", "tekst", "broj"}; assertThat ("grah", isIn (niz)); }
Također možemo provjeriti sadrži li niz zadane elemente bez obzira na redoslijed:
@Test javna praznina givenArrayAndValues_whenValuesFoundInArray_thenCorrect () {String [] hamcrestMatchers = {"zbirke", "grah", "tekst", "broj"}; assertThat (hamcrestMatchers, arrayContainingInAnyOrder ("grah", "zbirke", "broj", "tekst")); }
Da biste provjerili sadrži li niz zadane elemente, ali u danom redoslijedu:
@Test javna praznina givenArrayAndValues_whenValuesFoundInArrayInOrder_thenCorrect () {String [] hamcrestMatchers = {"zbirke", "grah", "tekst", "broj"}; assertThat (hamcrestMatchers, arrayContaining ("zbirke", "grah", "tekst", "broj")); }
Kad naš Kolekcija je Karta, možemo koristiti sljedeće podudarnosti u ovim odgovarajućim funkcijama:
Da biste provjerili sadrži li zadani ključ:
@Test javna praznina givenMapAndKey_whenKeyFoundInMap_thenCorrect () {Map map = new HashMap (); map.put ("ime bloga", "baeldung"); assertThat (map, hasKey ("blogname")); }
i zadana vrijednost:
@Test javna praznina givenMapAndValue_whenValueFoundInMap_thenCorrect () {Map map = new HashMap (); map.put ("ime bloga", "baeldung"); assertThat (map, hasValue ("baeldung")); }
i na kraju zadani unos (ključ, vrijednost):
@Test javna praznina givenMapAndEntry_whenEntryFoundInMap_thenCorrect () {Map map = new HashMap (); map.put ("ime bloga", "baeldung"); assertThat (map, hasEntry ("blogname", "baeldung")); }
7. The Broj Podudaranje
The Broj podudaranja se koriste za izvođenje tvrdnji o varijablama Broj razred.
Provjeriti većeNego stanje:
@Test javna praznina givenAnInteger_whenGreaterThan0_thenCorrect () {assertThat (1, većeThan (0)); }
Provjeriti većeNego ili jednak stanje:
@Test javna praznina givenAnInteger_whenGreaterThanOrEqTo5_thenCorrect () {assertThat (5, većaThanOrEqualTo (5)); }
Provjeriti manje od stanje:
@Test javna praznina givenAnInteger_whenLessThan0_thenCorrect () {assertThat (-1, lessThan (0)); }
Provjeriti manje od ili jednak stanje:
@Test javna praznina givenAnInteger_whenLessThanOrEqTo5_thenCorrect () {assertThat (-1, lessThanOrEqualTo (5)); }
Provjeriti blizu stanje:
@Test javna praznina danaADouble_whenCloseTo_thenCorrect () {assertThat (1.2, closeTo (1, 0.5)); }
Pazimo dobro na posljednju utakmicu, blizu. Prvi argument, operand, je onaj s kojim se uspoređuje cilj, a drugi argument je dopušteno odstupanje od operanda . To znači da ako je cilj operand + odstupanje ili odstupanje operanda, tada će test proći.
8. Podudaranje teksta
Tvrdnja o Nizs je olakšan, uredniji i intuitivniji Hamcrest‘S podudaranja teksta. Pogledat ćemo ih u ovom odjeljku.
Da biste provjerili je li Niz prazno je:
@Test javna praznina givenString_whenEmpty_thenCorrect () {String str = ""; assertThat (str, isEmptyString ()); }
Da biste provjerili je li Niz je prazna ili null:
@Test javna praznina givenString_whenEmptyOrNull_thenCorrect () {String str = null; assertThat (str, isEmptyOrNullString ()); }
Provjeriti jednakost dvoje Nizs zanemarujući bijeli prostor:
@Test javna praznina given2Strings_whenEqualRegardlessWhiteSpace_thenCorrect () {String str1 = "text"; Niz str2 = "tekst"; assertThat (str1, jednakToIgnoringWhiteSpace (str2)); }
Također možemo provjeriti prisutnost jedne ili više podniza u danoj Niz u danom redoslijedu:
@Test javna praznina givenString_whenContainsGivenSubstring_thenCorrect () {String str = "kaligrafija"; assertThat (str, stringContainsInOrder (Arrays.asList ("call", "graph"))); }
Napokon, možemo provjeriti jednakost dvoje Nizs bez obzira na slučaj:
@Test javna praznina given2Strings_whenEqual_thenCorrect () {String a = "foo"; Niz b = "FOO"; assertThat (a, jednakToIgnoringCase (b)); }
9. Core API
The Hamcrest temeljni API trebaju koristiti nezavisni dobavljači okvira. Međutim, nudi nam neke izvrsne konstrukcije kako bi naši jedinični testovi bili čitljiviji, a također i neke osnovne podudarnosti koje se mogu koristiti jednako lako.
Čitljivost s je konstruirati na podudarniku:
@Test javna praznina given2Strings_whenIsEqualRegardlessWhiteSpace_thenCorrect () {String str1 = "text"; Niz str2 = "tekst"; assertThat (str1, je (jednakToIgnoringWhiteSpace (str2))); }
The je konstruirati na jednostavnom tipu podataka:
@Test javna praznina given2Strings_whenIsEqual_thenCorrect () {String str1 = "text"; Niz str2 = "tekst"; assertThat (str1, je (str2)); }
Negacija s ne konstruirati na podudarniku:
@Test javna praznina given2Strings_whenIsNotEqualRegardlessWhiteSpace_thenCorrect () {String str1 = "text"; Niz str2 = "tekstovi"; assertThat (str1, ne (jednakToIgnoringWhiteSpace (str2))); }
The ne konstruirati na jednostavnom tipu podataka:
@Test javna praznina given2Strings_whenNotEqual_thenCorrect () {String str1 = "text"; Niz str2 = "tekstovi"; assertThat (str1, ne (str2)); }
Provjerite je li Niz sadrži zadani podniz:
@Test javna praznina danaAStrings_whenContainsAnotherGivenString_thenCorrect () {String str1 = "kaligrafija"; Niz str2 = "poziv"; assertThat (str1, containsString (str2)); }
Provjerite je li Niz započinje zadanim podnizom:
@Test javna praznina danaAString_whenStartsWithA AnotherGivenString_thenCorrect () {String str1 = "kaligrafija"; Niz str2 = "poziv"; assertThat (str1, startWith (str2)); }
Provjerite je li Niz završava zadanim podnizom:
@Test javna praznina givenAString_whenEndsWithAnotherGivenString_thenCorrect () {String str1 = "kaligrafija"; Niz str2 = "phy"; assertThat (str1, završavaWith (str2)); }
Provjerite jesu li dvije Objektsu iste instance:
@Test javna praznina given2Objects_whenSameInstance_thenCorrect () {Cat cat = new Cat (); assertThat (cat, sameInstance (cat)); }
Provjerite je li Objekt je instanca zadane klase:
@Test javna praznina givenAnObject_whenInstanceOfGivenClass_thenCorrect () {Mačka mačke = nova Mačka (); assertThat (cat, instanceOf (Cat.class)); }
Provjerite jesu li svi članovi a Kolekcija ispuniti uvjet:
@Test javna praznina givenList_whenEachElementGreaterThan0_thenCorrect () {Popis popisa = Arrays.asList (1, 2, 3); int baseCase = 0; assertThat (list, everyItem (većeTan (baseCase))); }
Provjerite je li Niz nije null:
@Test javna praznina givenString_whenNotNull_thenCorrect () {String str = "notnull"; assertThat (str, notNullValue ()); }
Lančani uvjeti zajedno, test prolazi kada cilj ispunjava bilo koji od uvjeta, sličnih logičnom ILI:
@Test javna praznina givenString_whenMeetsAnyOfGivenConditions_thenCorrect () {String str = "kaligrafija"; String start = "call"; Kraj niza = "foo"; assertThat (str, anyOf (startWith (start), containsString (end))); }
Lančani uvjeti zajedno, test prolazi samo kada cilj ispunjava sve uvjete, slično logičnom I:
@Test javna praznina givenString_whenMeetsAllOfGivenConditions_thenCorrect () {String str = "kaligrafija"; String start = "call"; Kraj niza = "phy"; assertThat (str, allOf (startWith (početak), završavaWith (kraj))); }
10. Prilagođeno podudaranje
Proširenjem možemo definirati vlastiti podudarnik TypeSafeMatcher. U ovom ćemo odjeljku stvoriti prilagođeno podudaranje koje omogućava prolazak testa samo kada je cilj pozitivan cijeli broj.
javna klasa IsPositiveInteger proširuje TypeSafeMatcher {javna void descriTo (Opis opisa) {description.appendText ("pozitivan cijeli broj"); } @Factory public static Matcher isAPositiveInteger () {return new IsPositiveInteger (); } @Override zaštićeni logički matchSafely (Integer integer) {return integer> 0; }}
Trebamo samo implementirati matchSafely metoda koja provjerava je li cilj zaista pozitivan cijeli broj i opišiTo metoda koja daje poruku o neuspjehu u slučaju da test ne prođe.
Evo testa koji koristi naše novo prilagođeno podudaranje:
@Test javna praznina givenInteger_whenAPositiveValue_thenCorrect () {int num = 1; assertThat (num, isAPositiveInteger ()); }
i evo poruke o neuspjehu koju dobivamo jer smo proslijedili u pozitivni cijeli broj:
java.lang.AssertionError: Očekivano: pozitivan cijeli broj, ali: was
11. Zaključak
U ovom uputstvu imamo istraživao Hamcrest API i naučio kako s njim možemo pisati bolje i održivije cjeline.
Potpuna implementacija svih ovih primjera i isječaka koda mogu se naći u mom Hamcrest github projektu.