Programavimas

Hamcrestas, kuriame yra rungtynių dalyviai

„Matchers“ klasės „Hamcrest 1.3 Javadoc“ dokumentuose pridėta daugiau kelių tos klasės metodų dokumentų nei buvo galima rasti „Hamcrest 1.2“. Pavyzdžiui, keturiuose perkrautuose metoduose yra aprašomesnė „Javadoc“ dokumentacija, kaip parodyta toliau parodytuose dviejuose palyginamojo ekrano momentiniuose vaizduose.

Nors galima išsiaiškinti, kaip veikia „sudėtiniai“ varžovai, tiesiog juos išbandydami, „Javadoc“ programoje „Hamcrest 1.3“ lengviau skaityti, kaip jie veikia. Daugelis „Java“ kūrėjų tikriausiai galvoja apie tokį elgesį kaip „String.contains“ („CharSequence“) arba „Collection.contains“ („Object“), kai galvoja apie yra () metodas. Kitaip tariant, dauguma „Java“ kūrėjų tikriausiai mano, kad „yra“ apibūdina, ar eilutėje / kolekcijoje yra pateikti simboliai / objektai, be kitų galimų simbolių / objektų. Tačiau „Hamcrest“ rungtynių dalyviams „sudėtyje“ yra daug konkretesnė prasmė. Kadangi „Hamcrest 1.3“ dokumentai yra daug aiškesni, „sudėtiniai“ atitikmenys yra daug jautresni elementų skaičiui ir elementų tvarkai, perduodamai šiems metodams.

Čia pateikti mano pavyzdžiai naudoja „JUnit“ ir „Hamcrest“. Čia svarbu pabrėžti, kad „Hamcrest“ JAR failas turi būti rodomas vieneto testų klasių kelyje prieš JUnit JAR failą, kitaip turiu naudoti „specialų“ JUnit JAR failą, sukurtą naudoti su atskiru „Hamcrest JAR“. Naudojant bet kurį iš šių būdų išvengiama „NoSuchMethodError“ ir kitų klaidų (sugedusių kaip org.hamcrest.Matcher.describeMismatch klaida), atsirandančių dėl nesutampančių klasių versijų. Apie šį „JUnit“ / „Hamcrest“ niuansą rašiau tinklaraščio įraše „Moving Beyond Core Hamcrest“ JUnit.

Kituose dviejuose ekrano momentiniuose vaizduose nurodomi vieneto testo kodo fragmentų, kuriuos vėliau rodau tinklaraštyje, rezultatai (kaip parodyta „NetBeans 7.3“), kad pademonstruočiau „Hamcrest“ turinčius atitikmenis. Manoma, kad testai turi tam tikrų nesėkmių (7 testai išlaikomi ir 4 testai neišlaikomi), kad būtų akivaizdu, kur „Hamcrest“ varžovai gali neveikti taip, kaip tikimasi, neperskaičius „Javadoc“. Pirmajame paveikslėlyje matomi tik 5 bandymai, 2 bandymai nepavyko ir 4 testai sukelia klaidų. Taip yra dėl to, kad „NetBeans“ projekto „Test Libraries“ klasėje aš prieš „Hamcrest“ įtraukiau „JUnit“. Antrasis paveikslėlis rodo laukiamus rezultatus, nes Hamcrest JAR įvyksta prieš JUnit JAR projekto „Test Libaries“ klasėje.

Šios demonstracijos tikslais turiu išbandyti paprastą sugalvotą klasę. To šaltinio kodas Pagrindinis klasė rodoma toliau.

Main.java

pakuotė dustin.pavyzdžiai; importuoti java.util.Collections; importuoti java.util.HashSet; importuoti java.util.Set; / ** * Pagrindinė klasė, kurią reikia išbandyti. * * @author Dustin * / public class Main {/ ** Naudoja „Java 7“ deimantų operatorių. * / private set stygos = new HashSet (); public Main () {} public Boolean addString (final String newString) {return this.strings.add (newString); } public set getStrings () {return Collections.unmodifiableSet (this.strings); }} 

Parodžius testuojamą klasę, dabar atėjo laikas apsvarstyti galimybę sukurti keletą „JUnit“ pagrįstų testų su „Hamcrest“ atitikmenimis. Konkrečiai, bandymai turi užtikrinti, kad eilutės būtų pridėtos per klasės „addString“ (eilutė) metodas yra jo pagrindas Nustatyti ir prieinama per „getStrings“ () metodas. Toliau parodyti vieneto bandymo metodai parodo, kaip tinkamai naudoti „Hamcrest“ atitikmenis, norint nustatyti, ar pridėtos stygos yra klasės pagrinde Nustatyti

Naudojant „Hamcrest“ yra () „Matcher“ su viena eilute rinkiniuose

 / ** * Šis testas bus išlaikytas, nes yra tik viena eilutė, todėl joje * bus ta vienintelė eilutė ir tvarka bus netiesiogiai teisinga. * / @Test public void testAddStringAndGetStringsWithContainsForSingleStringSoWorks () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); final Set stygos = subject.getStrings (); assertThat (eilutės, yra („Java“)); } 

Aukščiau pateiktas vieneto bandymas yra sėkmingas, nes Nustatyti joje yra tik viena eilutė, todėl eilutėmis tvarka ir skaičius išbandyti naudojant yra rungtynių rungtynės.

Naudojant „Hamcrest“ sudėtį yra tas pats elementų skaičius, jei užsakymai atitinka

 / ** * Kursas „sudėtyje“ tikisi tikslaus išdėstymo, o tai iš tikrųjų reiškia, kad jis neturėtų būti * naudojamas kartu su {@code Set} s. Paprastai veiks šis metodas *, o metodas tuo pačiu pavadinimu ir „2“ pabaigoje neveiks, arba * atvirkščiai. * / @Test public void testAddStringAndGetStringsWithContainsForMultipleStringsNotWorks1 () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat (eilutės, yra („Java“, „Groovy“)); } / ** * Kursas „yra“ tikisi tikslaus išdėstymo, o tai iš tikrųjų reiškia, kad jo * nereikėtų naudoti kartu su {@code Set} s. Paprastai šis metodas * veiks, o metodas su tuo pačiu pavadinimu ir „1“ pabaigoje neveiks, arba * atvirkščiai. * / @Test public void testAddStringAndGetStringsWithContainsForMultipleStringsNotWorks2 () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat (eilutės, yra („Groovy“, „Java“)); } 

Du aukščiau parodyti vieneto bandymų pavyzdžiai ir jų rezultatas, atlikus tą bandymą, kaip parodyta ankstesniame ekrano momentiniame vaizde, rodo, kad tol, kol argumentų skaičius yra () atitikiklis yra tas pats, kas bandomų kolekcijos eilučių skaičius - rungtynės Gegužė darbas jei išbandyti elementai yra ta pačia tvarka kaip ir kolekcijos elementai. Su neužsakytu Nustatyti, šia nutartimi negalima remtis, taigi yra () greičiausiai nebus tinkamas atitikmuo, kurį galima naudoti atliekant bandymą su a Nustatyti daugiau nei vieno elemento.

Naudojant „Hamcrest“ sudėtį su skirtingu elementų skaičiumi niekada neveikia

 / ** * Parodykite, kad yra neperduosite, kai bus klausiama kitokio * elementų, apie kuriuos yra klausiama, nei kolekcijoje. * / @Test public void testAddStringAndGetStringsWithContainsNotWorksDifferNumberElements1 () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat (eilutės, yra („Java“)); } / ** * Parodykite, kad yra neperduosite, kai bus pateiktas kitas * elementų, apie kuriuos teirautasi, skaičius nei kolekcijoje, net ir * kita tvarka. * / @Test public void testAddStringAndGetStringsWithContainsNotWorksDifferNumberElements2 () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat (eilutės, yra („Groovy“)); } 

Kaip rodo „JUnit“ bandymo rezultatai, šie du vieneto testai niekada neišlaikomi, nes bandomųjų elementų skaičius Nustatyti yra mažesnis nei elementų skaičius Nustatyti. Kitaip tariant, tai įrodo, kad yra () „matcher“ netikrina, ar tam tikras elementas yra kolekcijoje: jis tikrina, ar visi nurodyti elementai yra ir nurodyta tvarka. Kai kuriais atvejais tai gali būti per daug ribojanti, todėl dabar pereisiu prie kai kurių kitų rungtynių, kurias Hamcrestas numato nustatyti, ar elementas yra konkrečioje kolekcijoje.

Naudojant „Hamcrest“ yra „InInternet“ () atitikiklis

saturInAnyOrder atitikmuo nėra toks griežtas kaip yra () atitikmuo: jis leidžia išbandyti elementus bet kokia tvarka, kurioje yra surinkimo kolekcija.

 / ** * „Main“ klasės „addString“ ir „getStrings“ metodų bandymas naudojant „Hamcrest *“ atitikmenį yra „InAnyOrder“. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrder () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasCSharp = subject.addString ("C #"); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); galutinis loginis rezultatasScala = subject.addString ("Scala"); galutinis loginis rezultatasClojure = subject.addString ("Clojure"); final Set stygos = subject.getStrings (); assertThat (eilutės, yraInAnyOrder („Java“, „C #“, „Groovy“, „Scala“, „Clojure“)); } / ** * Naudokite tartalmazInAnyOrder ir parodykite, kad tvarka nėra svarbi tol, kol * visi pateikti įrašai yra kolekcijoje tam tikra tvarka. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrderAgain () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat (eilutės, yraInAnyOrder („Java“, „Groovy“)); assertThat (eilutės, yraInAnyOrder ("Groovy", "Java")); } 

Du iškart parodyti vieneto bandymai praeina, nepaisant to, kad bandomosios stygos buvo pateiktos saturInAnyOrder () atitikmenis kita tvarka, nei jie galėtų egzistuoti abiejose kolekcijose. Tačiau mažiau griežta saturInAnyOrder () „matcher“ vis tiek reikalauja, kad visi surinkimo elementai būtų perduoti. Šis vieneto testas neišlaikomas, nes ši sąlyga nėra įvykdyta.

 / ** * Tai nepavyks, nes, norint įtraukti „InInnyOrder“, visi elementai turi būti suderinti *, net jei ir kita tvarka. Bandant tik vieną elementą ir du * elementus kolekcijoje, jis vis tiek nepavyks. Kitaip tariant, užsakymas * nesvarbu su „insideInAnyOrder“, tačiau visus kolekcijos * elementus vis tiek reikia perduoti „matchingInAnyOrder“ atitikmeniui, tik ne ta pačia tvarka. * / @Test public void testAddStringAndGetStringsWithContainsInAnyOrderDiffNumberElements () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat (eilutės, yraInAnyOrder („Java“)); } 

„Hamcrest“ „hasItem“ () ir „hasItems“ (Matchers) veikia kaip garsai

Kaip parodyta kituose dviejuose bandymo metoduose (kurie abu praeina), „Hamcrest“ hasItem () (vienai prekei) ir hasItems (keliems daiktams) sėkmingai patikrina, ar kolekcijoje yra vienas ar daugiau nurodytų elementų, neatsižvelgiant į nurodytų prekių užsakymą ar skaičių. Tai tikrai veikia labiau, nes dauguma „Java“ kūrėjų yra įpratę „turėti“ darbą dirbant su stygomis ir kolekcijomis.

 / ** * Demonstrate hasItem () taip pat veiks nustatant, ar kolekcijoje yra * tam tikras elementas. * / @Test public void testAddStringAndGetStringsWithHasItem () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat (eilutės, hasItem ("Groovy")); assertThat (eilutės, hasItem ("Java")); } / ** * Parodykite, kad „hasItems“ veikia nustatant, ar kolekcijoje yra vienas ar daugiau elementų ir kad daiktų skaičius ir prekių eiliškumas * nėra reikšmingi nustatant atitiktį / nesėkmę. * / @Test public void testAddStringAndGetStringsWithHasItems () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat (eilutės, hasItems ("Groovy", "Java")); assertThat (eilutės, hasItems („Java“, „Groovy“)); assertThat (stygos, hasItems ("Groovy")); assertThat (eilutės, hasItems („Java“)); } 

Hamcrestas yra () varžovas išbando varžybas iš kitos krypties

Ką tik aptartas hasItem () ir „hasItems“ () rungtynių dalyviai yra mažiau griežti nei yra () ir dar mažiau griežta nei saturInAnyOrder () ir dažnai to norisi, kai norima paprasčiausiai įsitikinti, kad vienas ar keli daiktai yra kažkur kolekcijoje, nesijaudindami dėl tos prekės eilės toje kolekcijoje ar kad kiti galimi daiktai yra toje kolekcijoje. Vienas kitas būdas naudoti „Hamcrest“ tam pačiam santykiui nustatyti, bet iš priešingos perspektyvos, yra naudojimas yra degtukas. yra atitikmuo nustato, ar daiktas yra kažkur su atitikmeniui pateiktomis kolekcijomis, neatsižvelgdamas į tos prekės užsakymą kolekcijoje, ar tame, kuriame yra kolekcija, yra kitų daiktų.

 / ** * Norėdami išbandyti atskirą elementą, naudokite isIn matcher pateiktoje kolekcijoje. * / @Test public void testAddStringAndGetStringsWithIsIn () {final Pagrindinis dalykas = naujas Pagrindinis (); galutinis loginis rezultatasJava = subject.addString („Java“); galutinis loginis rezultatasGroovy = subject.addString ("Groovy"); final Set stygos = subject.getStrings (); assertThat („Groovy“, isIn (stygos)); assertThat („Java“, isIn (eilutės)); } 
$config[zx-auto] not found$config[zx-overlay] not found