Programmēšana

JUnit 5 apmācība, 1. daļa: Vienības testēšana ar JUnit 5, Mockito un Hamcrest

JUnit 5 ir jauns de facto standarts vienības testu izstrādei Java. Šī jaunākā versija ir atstājusi Java 5 ierobežojumus un integrējusi daudzas Java 8 funkcijas, jo īpaši atbalstu lambda izteiksmēm.

Šajā divdaļīgā JUnit 5 ievaddaļas pirmajā pusē jūs sāksit testēšanu ar JUnit 5. Es jums parādīšu, kā konfigurēt Maven projektu, lai izmantotu JUnit 5, kā rakstīt testus, izmantojot @Pārbaude un @ParameterizedTest anotācijas un kā strādāt ar jaunajām dzīves cikla piezīmēm JUnit 5. Tiks parādīts arī īss filtru tagu izmantošanas piemērs, un es parādīšu, kā JUnit 5 integrēt trešās puses apgalvojumu bibliotēkā - šajā gadījumā , Hamkresta. Visbeidzot, jūs saņemsiet ātru, pamācošu ievadu par JUnit 5 integrēšanu ar Mockito, lai jūs varētu uzrakstīt stingrākus vienību testus sarežģītām, reālās pasaules sistēmām.

lejupielādēt Iegūt kodu Iegūstiet šīs apmācības piemēru avota kodu. Izveidoja Steven Haines JavaWorld.

Testu vadīta izstrāde

Ja jūs kādu laiku esat izstrādājis Java kodu, jūs, iespējams, esat cieši iepazinies ar testu balstītu izstrādi, tāpēc es šo sadaļu īsi. Ir svarīgi saprast kāpēc mēs tomēr rakstām vienības testus, kā arī stratēģijas, kuras izstrādātāji izmanto, izstrādājot vienību testus.

Testa virzīta izstrāde (TDD) ir programmatūras izstrādes process, kas savij kodēšanu, testēšanu un projektēšanu. Tā ir testa pārbaude, kuras mērķis ir uzlabot jūsu lietojumprogrammu kvalitāti. Testu vadītu attīstību nosaka šāds dzīves cikls:

  1. Pievienojiet testu.
  2. Izpildiet visus savus testus un novērojiet, kā jaunais tests neizdodas.
  3. Ieviesiet kodu.
  4. Izpildiet visus savus testus un novērojiet, kā jaunais tests ir veiksmīgs.
  5. Refaktors kods.

1. attēlā parādīts šis TDD dzīves cikls.

Stīvens Heinss

Pirms koda rakstīšanas testu rakstīšanai ir divi mērķi. Pirmkārt, tas liek domāt par biznesa problēmu, kuru mēģināt atrisināt. Piemēram, kā būtu jāuzvedas veiksmīgiem scenārijiem? Kādiem apstākļiem vajadzētu neizdoties? Kā viņiem vajadzētu izgāzties? Otrkārt, testēšana vispirms dod lielāku pārliecību par testiem. Ikreiz, kad es uzrakstu testus pēc koda uzrakstīšanas, man tie vienmēr ir jāsalauž, lai pārliecinātos, ka tie patiešām uztver kļūdas. Rakstot testus, vispirms tiek izvairīts no šī papildu soļa.

Rakstīt testus laimīgajam ceļam parasti ir viegli: ņemot vērā labu ieguldījumu, klasei jāatgriež deterministiska atbilde. Bet negatīvu (vai neveiksmju) testa gadījumu rakstīšana, īpaši sarežģītiem komponentiem, var būt sarežģītāka.

Kā piemēru apsveriet testu rakstīšanu datu bāzes krātuvei. Uz laimīgā ceļa mēs ievietojam ierakstu datu bāzē un saņemam atpakaļ izveidoto objektu, ieskaitot visas ģenerētās atslēgas. Patiesībā mums jāņem vērā arī konflikta iespējamība, piemēram, ieraksta ievietošana ar unikālu kolonnas vērtību, kas jau atrodas citā ierakstā. Turklāt, kas notiek, ja repozitorijs nevar izveidot savienojumu ar datu bāzi, iespējams, tāpēc, ka ir mainīts lietotājvārds vai parole? Kas notiek, ja tranzītā ir tīkla kļūda? Kas notiks, ja pieprasījums netiks izpildīts jūsu noteiktajā taimauta ierobežojumā?

Lai izveidotu stabilu komponentu, jums jāapsver visi iespējamie un maz ticamie scenāriji, jāizstrādā tiem testi un jāuzraksta kods, lai tie atbilstu šiem testiem. Turpmāk rakstā mēs aplūkosim dažādu kļūmju scenāriju izveidošanas stratēģijas, kā arī dažas no jaunajām JUnit 5 funkcijām, kas var palīdzēt pārbaudīt šos scenārijus.

5. JUnit pieņemšana

Ja kādu laiku esat lietojis JUnit, dažas no 5. JUnit izmaiņām būs korekcijas. Šeit ir augsta līmeņa kopsavilkums par to, kas atšķiras starp abām versijām:

  • JUnit 5 tagad ir iepakots org.junit.jupiter grupa, kas maina to, kā jūs to iekļausit savos Maven un Gradle projektos.
  • JUnit 4 vajadzēja vismaz JDK 5 JDK; 5. JUnit nepieciešama vismaz JDK 8.
  • 4. JUnits @Pirms, @BeforeClass, @Pēc, un @Pēcstundas anotācijas ir aizstātas ar @PirmsKatrs, @BeforeAll, @PēcKatrs, un @Galu galā, attiecīgi.
  • 4. JUnits @ Ignorēt anotācija ir aizstāta ar @ Invalīds anotācija.
  • The @Kategorija anotācija ir aizstāta ar @Tag anotācija.
  • JUnit 5 pievieno jaunu apgalvojumu metožu kopumu.
  • Skrējēji ir aizstāti ar paplašinājumiem, ar jaunu API paplašinājumu ieviesējiem.
  • JUnit 5 ievieš pieņēmumus, kas pārtrauc testa izpildi.
  • JUnit 5 atbalsta ligzdotas un dinamiskas testa klases.

Šajā rakstā mēs izpētīsim lielāko daļu šo jauno funkciju.

Vienības testēšana ar JUnit 5

Sāksim vienkārši, izmantojot projekta konfigurēšanas piemēru, lai JUnit 5 izmantotu vienības pārbaudei. 1. saraksts parāda a MathTools klase, kuras metode pārveido skaitītāju un saucēju par a dubultā.

Saraksts 1. JUnit 5 projekta piemērs (MathTools.java)

 pakete com.javaworld.geekcap.math; publiskā klase MathTools {public static double convertToDecimal (int skaitītājs, int saucējs) {if (saucējs == 0) {mest jaunu IllegalArgumentException ("saucējs nedrīkst būt 0"); } atgriešanās (dubultā) skaitītājs / (dubultā) saucējs; }}

Mums ir divi galvenie scenāriji, lai pārbaudītu MathTools klase un tās metode:

  • A derīgs tests, kurā skaitītājam un saucējam mēs nododam veselus skaitļus, kas nav nulle.
  • A neveiksmes scenārijs, kurā mēs nododam saucēja nulles vērtību.

2. sarakstā parādīta JUnit 5 testa klase, lai pārbaudītu šos divus scenārijus.

Saraksts 2. JUnit 5 testa klase (MathToolsTest.java)

 pakete com.javaworld.geekcap.math; importēt java.lang.IllegalArgumentException; importēt org.junit.jupiter.api.Assertions; importēt org.junit.jupiter.api.Test; klase MathToolsTest {@Test void testConvertToDecimalSuccess () {double result = MathTools.convertToDecimal (3, 4); Apgalvojumi.assertEquals (0,75, rezultāts); } @Test void testConvertToDecimalInvalidDenominator () {Assertions.assertThrows (IllegalArgumentException.class, () -> MathTools.convertToDecimal (3, 0)); }}

Sarakstā 2 testConvertToDecimalInvalidDenominator metode izpilda MathTools :: convertToDecimal metode iekšpusē assertThrows zvanu. Pirmais arguments ir paredzamais izmetamo izņēmumu veids. Otrais arguments ir funkcija, kas radīs šo izņēmumu. The assertThrows metode izpilda funkciju un apstiprina, ka tiek izmests paredzamais izņēmuma veids.

Klase Apgalvojumi un tās metodes

Theorg.junit.jupiter.api.Test anotācija apzīmē testa metodi. Ņemiet vērā, ka @Pārbaude anotācija tagad nāk no JUnit 5 Jupiter API pakotnes, nevis JUnit 4 pakotnes org.junit iepakojums. The testConvertToDecimalSuccess metode vispirms izpilda MathTools :: convertToDecimal metodi ar skaitītāju 3 un saucēju 4, tad apgalvo, ka rezultāts ir vienāds ar 0,75. The org.junit.jupiter.api.Apgalvojumi klase nodrošina komplektu statisks metodes faktisko un paredzamo rezultātu salīdzināšanai. The Apgalvojumi klasei ir šādas metodes, kas aptver lielāko daļu primitīvo datu tipu:

  • assertArrayEquals salīdzina faktiskā masīva saturu ar paredzamo masīvu.
  • apgalvotEquals salīdzina faktisko vērtību ar paredzamo vērtību.
  • assertNotEquals salīdzina divas vērtības, lai apstiprinātu, ka tās nav vienādas.
  • apgalvotPatiesa apstiprina, ka norādītā vērtība ir patiesa.
  • apgalvotFalse apstiprina, ka norādītā vērtība ir nepatiesa.
  • assertLinesMatch salīdzina divus sarakstus Stīgas.
  • apgalvotNull apstiprina, ka norādītā vērtība nav derīga.
  • assertNotNull apstiprina, ka norādītā vērtība nav nulle.
  • apgalvot, pats apstiprina, ka divas vērtības attiecas uz vienu un to pašu objektu.
  • assertNotSame apstiprina, ka divas vērtības neattiecas uz vienu un to pašu objektu.
  • assertThrows apstiprina, ka metodes izpilde rada paredzamo izņēmumu (to varat redzēt testConvertToDecimalInvalidDenominator piemērs iepriekš).
  • assertTimeout apstiprina, ka piegādāto funkciju izpilda noteiktā noildzes laikā.
  • assertTimeoutPreemptively apstiprina, ka piegādātā funkcija tiek pabeigta noteiktā taimautā, bet, kad ir iestājies taimauts, tā nogalina funkcijas izpildi.

Ja kāda no šīm apgalvošanas metodēm neizdodas, vienības tests tiek atzīmēts kā neizdevies. Šis paziņojums par kļūmi tiks ierakstīts ekrānā, kad izpildīsit testu, un pēc tam tiks saglabāts pārskata failā.

Delta izmantošana ar assertEquals

Lietojot peldēt un dubultā vērtības apgalvotEquals, varat norādīt arī a delta kas apzīmē atšķirības slieksni starp abiem. Mūsu piemērā mēs būtu varējuši pievienot deltu 0,001 gadījumā, ja 0,75 faktiski tika atgriezts kā 0,750001.

Testa rezultātu analīze

Papildus vērtības vai uzvedības apstiprināšanai, apgalvot metodes var pieņemt arī kļūdas tekstuālu aprakstu, kas var palīdzēt diagnosticēt kļūmes. Piemēram:

 Assertions.assertEquals (0,75, rezultāts, "The MathTools :: convertToDecimal vērtība neatgrieza pareizo vērtību 0,75 par 3/4"); Assertions.assertEquals (0,75, rezultāts, () -> "The MathTools :: convertToDecimal vērtība neatgrieza pareizo vērtību 0,75 vērtībai 3/4"; 

Rezultātā tiks parādīta paredzamā vērtība 0,75 un faktiskā vērtība. Tas parādīs arī norādīto ziņojumu, kas var palīdzēt izprast kļūdas kontekstu. Atšķirība starp abiem variantiem ir tā, ka pirmais vienmēr izveido ziņojumu, pat ja tas netiek parādīts, savukārt otrais veido ziņojumu tikai tad, ja apgalvojums neizdodas. Šajā gadījumā ziņojuma uzbūve ir niecīga, tāpēc tam nav īsti nozīmes. Tomēr testam, kas nokārtots, nav jāveido kļūdas ziņojums, tāpēc parasti ir ieteicams izmantot otro stilu.

Visbeidzot, ja testu veikšanai izmantojat tādu IDE kā IntelliJ, katra testa metode tiks parādīta ar tās metodes nosaukumu. Tas ir labi, ja jūsu metožu nosaukumi ir lasāmi, bet jūs varat arī pievienot @DisplayName jūsu testa metožu anotācija, lai labāk identificētu testus:

@Test @DisplayName ("Pārbaudīt veiksmīgu decimālo konvertēšanu") void testConvertToDecimalSuccess () {double result = MathTools.convertToDecimal (3, 4); Apgalvojumi.assertEquals (0,751, rezultāts); }

Vienības testa veikšana

Lai palaistu JUnit 5 testus no Maven projekta, jums jāiekļauj spraudnis maven-surefire Mavenā pom.xml failu un pievienojiet jaunu atkarību. 3. sarakstā parādīts pom.xml failu šim projektam.

Saraksts 3. Maven pom.xml JUnit 5 projekta piemēram

  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 tests 

JUnit 5 atkarības

JUnit 5 komponentus iesaiņo org.junit.jupiter grupa, un mums jāpievieno junits-jupiters artefakts, kas ir apkopotājs artefakts, kas importē šādas atkarības:

  • junit-jupiter-api definē API testu un paplašinājumu rakstīšanai.
  • junit-jupiter-dzinējs ir testa dzinēja ieviešana, kas veic vienības testus.
  • junit-jupiter-params nodrošina atbalstu parametrizētiem testiem.

Tālāk mums jāpievieno spraudnis maven-surefire izveidot spraudni, lai palaistu testus.

Visbeidzot, noteikti iekļaujiet maven-compiler-plugin ar Java 8 vai jaunāku versiju, lai jūs varētu izmantot Java 8 funkcijas, piemēram, lambdas.

Palaidiet to!

Izmantojiet šo komandu, lai palaistu testa klasi no IDE vai Maven:

mvn tīrs tests

Ja jums veicas, jums vajadzētu redzēt līdzīgu izvadi kā šis:

 [INFO] ----------------------------------------------- -------- [INFO] TESTI [INFO] ----------------------------------- -------------------- [INFO] Darbojas com.javaworld.geekcap.math.MathToolsTest [INFO] Testi veikti: 2, Kļūdas: 0, Kļūdas: 0, Izlaista : 0, Pagājušais laiks: 0,04 s - in com.javaworld.geekcap.math.MathToolsTest [INFO] [INFO] Rezultāti: [INFO] [INFO] Pārbaudītie testi: 2, Kļūdas: 0, Kļūdas: 0, Izlaistie: 0 [ INFO] [INFO] --------------------------------------------- --------------------------- [INFO] VEICINĀT panākumus [INFO] --------------- -------------------------------------------------- ------- [INFO] Kopējais laiks: 3.832 s [INFO] Pabeigts: 2020-02-16T08: 21: 15-05: 00 [INFO] ------------- -------------------------------------------------- --------- 
$config[zx-auto] not found$config[zx-overlay] not found