Programavimas

„JUnit 5“ pamoka, 1 dalis: Vieneto testavimas naudojant „JUnit 5“, „Mockito“ ir „Hamcrest“

„JUnit 5“ yra naujas de facto standartas, skirtas kurti vieneto testus „Java“. Ši naujausia versija paliko „Java 5“ apribojimus ir integravo daugybę „Java 8“ funkcijų, ypač palaikant „lambda“ išraiškas.

Šioje pirmoje dviejų dalių „JUnit 5“ įvado pusėje pradėsite bandymus su „JUnit 5“. Aš jums parodysiu, kaip sukonfigūruoti „Maven“ projektą naudoti „JUnit 5“, kaip rašyti testus naudojant @Test ir @ParameterizedTest anotacijos ir kaip dirbti su naujomis gyvenimo ciklo anotacijomis „JUnit 5“. Taip pat pamatysite trumpą filtro žymų naudojimo pavyzdį ir parodysiu, kaip integruoti „JUnit 5“ su trečiųjų šalių tvirtinimų biblioteka - šiuo atveju , Hamcrestas. Galiausiai gausite greitą pamoką apie „JUnit 5“ integravimą su „Mockito“, kad galėtumėte parašyti patikimesnius sudėtingų, realaus pasaulio sistemų bandymus.

atsisiųsti Gauti kodą Gaukite šios instrukcijos pavyzdžių šaltinio kodą. Stevenas Hainesas sukūrė „JavaWorld“.

Testais pagrįstas kūrimas

Jei kurį laiką kūrėte „Java“ kodą, tikriausiai esate gerai susipažinęs su bandomaisiais kūrimais, todėl trumpai aprašysiu šį skyrių. Svarbu suprasti kodėl mes rašome vieneto testus, taip pat strategijas, kurias kūrėjai taiko kurdami vieneto testus.

Test-driven development (TDD) yra programinės įrangos kūrimo procesas, persipinantis kodavimą, testavimą ir dizainą. Tai bandymų metodas, kurio tikslas - pagerinti jūsų programų kokybę. Testu pagrįstą kūrimą apibrėžia toks gyvenimo ciklas:

  1. Pridėkite testą.
  2. Atlikite visus savo testus ir stebėkite, ar naujas testas nepavyko.
  3. Įdiegti kodą.
  4. Atlikite visus savo testus ir stebėkite, kaip naujas testas sekasi.
  5. Refaktorius kodas.

1 paveiksle parodytas šis TDD gyvavimo ciklas.

Stevenas Hainesas

Testų rašymas prieš rašant kodą yra dvigubas. Pirma, tai priverčia susimąstyti apie verslo problemą, kurią bandote išspręsti. Pavyzdžiui, kaip turėtų elgtis sėkmingi scenarijai? Kokios sąlygos turėtų žlugti? Kaip jie turėtų žlugti? Antra, testavimas pirmiausia suteikia daugiau pasitikėjimo savo testais. Kai rašau testus parašęs kodą, visada turiu juos sulaužyti, kad įsitikinčiau, jog jie iš tikrųjų gaudo klaidas. Rašant testus pirmiausia išvengiama šio papildomo žingsnio.

Rašyti laimingo kelio testus paprastai yra lengva: turėdami gerą indėlį, klasė turėtų pateikti deterministinį atsakymą. Tačiau neigiamų (arba nesėkmingų) testų, ypač sudėtingų komponentų, rašymas gali būti sudėtingesnis.

Kaip pavyzdį apsvarstykite testų rašymą duomenų bazės saugyklai. Laimingame kelyje įterpiame įrašą į duomenų bazę ir gauname atgal sukurtą objektą, įskaitant visus sugeneruotus raktus. Iš tikrųjų turime atsižvelgti ir į konflikto galimybę, pavyzdžiui, įterpti įrašą su unikalia stulpelio verte, kurią jau turi kitas įrašas. Be to, kas nutinka, kai saugykla negali prisijungti prie duomenų bazės, galbūt dėl ​​to, kad pasikeitė vartotojo vardas ar slaptažodis? Kas nutiks, jei keliaujant įvyko tinklo klaida? Kas nutiks, jei užklausa nebus įvykdyta per nustatytą skirtąjį laiką?

Norėdami sukurti tvirtą komponentą, turite atsižvelgti į visus tikėtinus ir mažai tikėtinus scenarijus, sukurti jiems skirtus testus ir parašyti kodą, kad tenkintumėte šiuos testus. Vėliau straipsnyje apžvelgsime skirtingų gedimų scenarijų kūrimo strategijas ir keletą naujų „JUnit 5“ funkcijų, kurios gali padėti išbandyti tuos scenarijus.

5 JUnito priėmimas

Jei kurį laiką naudojote „JUnit“, kai kurie „JUnit 5“ pakeitimai bus koregavimas. Štai aukšto lygio santrauka, kas skiriasi abiejose versijose:

  • JUnit 5 dabar supakuotas į org.junit.jupiter grupę, kuri keičia tai, kaip įtrauksite ją į savo „Maven“ ir „Gradle“ projektus.
  • 4 JUnitui reikalingas minimalus JDK 5 JDK; 5 JUnitui reikalingas mažiausiai 8 JDK.
  • 4 „JUnit“ @Prieš, @BeforeClass, @Poir @Po pamokų anotacijos pakeistos @ Prieš kiekvieną, @BeforeAll, @ Po kiekvienoir @Po visko, atitinkamai.
  • 4 „JUnit“ @ Ignoruoti anotacija pakeista @ Neįgalus anotacija.
  • @Kategorija anotacija pakeista @Tag anotacija.
  • „JUnit 5“ prideda naują teiginių metodų rinkinį.
  • Bėgikai buvo pakeisti plėtiniais su nauja API plėtinių diegėjams.
  • „JUnit 5“ pateikia prielaidas, kurios sustabdo testo vykdymą.
  • „JUnit 5“ palaiko įdėtas ir dinamines testų klases.

Daugumą šių naujų funkcijų išnagrinėsime šiame straipsnyje.

Įrenginio testavimas naudojant „JUnit 5“

Pradėkime nuo paprasto projekto sukonfigūravimo, kad JUnit 5 būtų naudojamas vieneto bandymui, pavyzdys. 1 sąrašas rodo a „MathTools“ klasė, kurios metodas skaitiklį ir vardiklį paverčia a dvigubai.

Sąrašas 1. „JUnit 5“ projekto pavyzdys (MathTools.java)

 paketas com.javaworld.geekcap.math; public class MathTools {public static double convertToDecimal (int skaitiklis, int vardiklis) {if (vardiklis == 0) {mesti naują IllegalArgumentException ("vardiklis neturi būti 0"); } grįžti (dvigubas) skaitiklis / (dvigubas) vardiklis; }}

Turime du pagrindinius scenarijus, kaip išbandyti „MathTools“ klasė ir jos metodas:

  • A galiojantis testas, kuriame skaitikliui ir vardikliui perduodame ne nulinius sveikuosius skaičius.
  • A nesėkmės scenarijus, kuriame perduodame vardiklio nulinę vertę.

2 sąraše rodoma „JUnit 5“ testų klasė, skirta išbandyti šiuos du scenarijus.

2 sąrašas. „JUnit 5“ testų klasė (MathToolsTest.java)

 paketas com.javaworld.geekcap.math; importuoti java.lang.IllegalArgumentException; importuoti org.junit.jupiter.api.Aertertions; importuoti org.junit.jupiter.api.Test; klasė „MathToolsTest“ {@Test void testConvertToDecimalSuccess () {dvigubas rezultatas = MathTools.convertToDecimal (3, 4); Teiginiai.assertEquals (0,75, rezultatas); } @Test void testConvertToDecimalInvalidDenominator () {Assertions.assertThrows (IllegalArgumentException.class, () -> MathTools.convertToDecimal (3, 0)); }}

2 sąraše testConvertToDecimalInvalidDenominator metodas vykdo „MathTools“ :: convertToDecimal metodas assertThrows skambutis. Pirmasis argumentas yra numatoma išimties rūšis. Antrasis argumentas yra funkcija, kuri išmes tą išimtį. assertThrows metodas vykdo funkciją ir patvirtina, kad laukiama išimties rūšis.

Teiginių klasė ir jos metodai

org.junit.jupiter.api.Test anotacija žymi bandymo metodą. Atkreipkite dėmesį, kad @Test anotacija dabar gaunama iš „JUnit 5 Jupiter“ API paketo, o ne „JUnit 4“ org.junit pakuotė. testConvertToDecimalSuccess metodas pirmiausia vykdo „MathTools“ :: convertToDecimal metodas su skaitikliu 3 ir vardikliu 4, tada tvirtina, kad rezultatas yra lygus 0,75. org.junit.jupiter.api.Tvirtinimai klasė pateikia rinkinį statinis faktinių ir laukiamų rezultatų palyginimo metodai. Teiginiai klasėje naudojami šie metodai, kurie apima daugumą pirminių duomenų tipų:

  • assertArrayEquals palygina faktinio masyvo turinį su numatomu masyvu.
  • tvirtintiEquals palygina faktinę vertę su numatoma verte.
  • assertNotEquals palygina dvi reikšmes, kad patvirtintų, jog jos nėra lygios.
  • teigtiTiesa patvirtina, kad pateikta vertė yra teisinga.
  • teigtiKlaidinga patvirtina, kad pateikta vertė yra klaidinga.
  • assertLinesMatch palyginami du sąrašai Stygoss.
  • tvirtintiNullas patvirtina, kad pateikta reikšmė yra nulinė.
  • assertNotNull patvirtina, kad pateikta reikšmė nėra nulinė.
  • tvirtintiTas pats patvirtina, kad dvi reikšmės nurodo tą patį objektą.
  • assertNotSame patvirtina, kad dvi reikšmės nenurodo to paties objekto.
  • assertThrows patvirtina, kad metodo vykdymas sukelia laukiamą išimtį (tai galite pamatyti testConvertToDecimalInvalidDenominator aukščiau pateiktas pavyzdys).
  • assertTimeout patvirtina, kad tiekiama funkcija baigiama per nurodytą laiką.
  • assertTimeoutPreemptively patvirtina, kad tiekiama funkcija baigiama per nurodytą skirtąjį laiką, tačiau pasiekus skirtąjį laiką, funkcija bus vykdoma.

Jei kuris nors iš šių tvirtinimo metodų nepavyksta, vieneto bandymas pažymimas kaip nepavykęs. Šis pranešimas apie gedimą bus įrašytas ekrane, kai atliksite bandymą, tada bus išsaugotas ataskaitos faile.

Delta naudojimas su „assertEquals“

Naudojant plūdė ir dvigubai vertės tvirtintiEquals, taip pat galite nurodyti a delta tai reiškia abiejų skirtumų slenkstį. Mūsų pavyzdyje galėjome pridėti delta 0,001, jei 0,75 būtų iš tikrųjų grąžinta kaip 0,750001.

Analizuodami savo testo rezultatus

Be vertės ar elgesio patvirtinimo, tvirtinti metodai taip pat gali priimti tekstinį klaidos aprašymą, kuris gali padėti diagnozuoti gedimus. Pavyzdžiui:

 „Assertions.assertEquals“ (0,75, rezultatas, „The MathTools :: convertToDecimal“ reikšmė 3/4 nepateikė teisingos vertės 0,75 “); Assertions.assertEquals (0,75, rezultatas, () -> "The MathTools :: convertToDecimal reikšmė 3/4 atveju negrąžino teisingos vertės 0,75"; 

Rezultatas parodys laukiamą 0,75 vertę ir faktinę vertę. Taip pat bus rodomas nurodytas pranešimas, kuris gali padėti suprasti klaidos kontekstą. Skirtumas tarp dviejų variantų yra tas, kad pirmasis visada sukuria pranešimą, net jei jis nerodomas, o antrasis sukuria pranešimą tik tuo atveju, jei teiginys nepavyksta. Šiuo atveju pranešimo konstrukcija yra nereikšminga, todėl tai visiškai nesvarbu. Visgi, testo, kuris praeina, klaidos pranešimo kurti nereikia, todėl dažniausiai geriausia naudoti antrąjį stilių.

Galiausiai, jei bandymams atlikti naudojate tokią IDE, kaip „IntelliJ“, kiekvienas bandymo metodas bus rodomas jo metodo pavadinimu. Tai gerai, jei jūsų metodo pavadinimai yra skaitomi, tačiau taip pat galite pridėti @Rodomas pavadinimas bandymų metodų anotacija, kad būtų galima geriau nustatyti testus:

@Test @DisplayName ("Sėkmingo dešimtainio konvertavimo bandymas") negalioja testConvertToDecimalSuccess () {dvigubas rezultatas = MathTools.convertToDecimal (3, 4); Teiginiai.assertEquals (0,751, rezultatas); }

Vieneto testo vykdymas

Norėdami vykdyti „JUnit 5“ testus iš „Maven“ projekto, turite įtraukti „maven-surefire-plugin“ Mavene pom.xml failą ir pridėkite naują priklausomybę. 3 sąraše rodoma pom.xml failą šiam projektui.

3. „Maven pom.xml“ sąrašas „JUnit 5“ projekto pavyzdžiui

  4.0.0 com.javaworld.geekcap junit5 jar 1.0-SNAPSHOT org.apache.maven.plugins maven-compiler-plugin 3.8.1 8 8 org.apache.maven.plugins maven-surefire-plugin 3.0.0-M4 junit5 // maven.apache.org org.junit.jupiter junit-jupiter 5.6.0 testas 

JUnit 5 priklausomybės

JUnit 5 savo komponentus pakuoja į org.junit.jupiter grupę ir turime pridėti junitas-jupiteris artefaktas, kuris yra kaupiklis, kuris importuoja šias priklausomybes:

  • junit-jupiter-api apibrėžia testų ir plėtinių rašymo API.
  • junit-jupiter-variklis yra bandomojo variklio įgyvendinimas, vykdantis vieneto bandymus.
  • junit-jupiter-params teikia paramą parametrų bandymams.

Toliau turime pridėti „maven-surefire-plugin“ sukurti papildinį, kad būtų galima atlikti bandymus.

Galiausiai būtinai įtraukite „maven-compiler-plugin“ su „Java 8“ ar naujesne versija, kad galėtumėte naudoti „Java 8“ funkcijas, pvz., „lambdas“.

Paleisk tai!

Norėdami paleisti bandymo klasę iš savo IDE arba iš „Maven“, naudokite šią komandą:

mvn švarus testas

Jei jums pasiseks, turėtumėte pamatyti išvestį, panašią į šią:

 [INFORMACIJA] ----------------------------------------------- -------- [INFO] BANDYMAI [INFO] ----------------------------------- -------------------- [INFO] Veikia com.javaworld.geekcap.math.MathToolsTest [INFO] Testai vykdomi: 2, Gedimai: 0, Klaidos: 0, Praleisti : 0, Praėjęs laikas: 0.04 s - in com.javaworld.geekcap.math.MathToolsTest [INFO] [INFO] Rezultatai: [INFO] [INFO] Bandymai atlikti: 2, Gedimai: 0, Klaidos: 0, Praleisti: 0 [ INFO] [INFO] --------------------------------------------- --------------------------- [INFO] PASTATYKITE SĖKM [[INFO] --------------- -------------------------------------------------- ------- [INFO] Bendras laikas: 3.832 s [INFO] Baigta: 2020-02-16T08: 21: 15-05: 00 [INFO] ------------- -------------------------------------------------- ---------