JUnit 5 je nový de facto standard pro vývoj testů jednotek v Javě. Tato nejnovější verze zanechala omezení v prostředí Java 5 a integrovala mnoho funkcí z prostředí Java 8, zejména podporu výrazů lambda.
V této první polovině dvoudílného úvodu do JUnit 5 začnete s testováním pomocí JUnit 5. Ukážu vám, jak nakonfigurovat projekt Maven tak, aby používal JUnit 5, jak psát testy pomocí @Test
a @ParameterizedTest
anotace a jak pracovat s novými anotacemi životního cyklu v JUnit 5. Uvidíte také krátký příklad použití značek filtrů a ukážu vám, jak integrovat JUnit 5 s knihovnou tvrzení třetích stran - v tomto případě , Hamcrest. Nakonec získáte rychlý výukový úvod k integraci JUnit 5 s Mockito, abyste mohli psát robustnější testy jednotek pro složité systémy v reálném světě.
Testovaný vývoj
Pokud jste vyvíjeli kód Java pro jakékoli časové období, jste pravděpodobně důvěrně obeznámeni s vývojem řízeným testem, takže tuto část stručně uvedu. Je důležité to pochopit proč píšeme jednotkové testy, ale také strategie, které vývojáři používají při navrhování jednotkových testů.
Test-driven development (TDD) je proces vývoje softwaru, který prolíná kódování, testování a design. Jedná se o testovací přístup, jehož cílem je zlepšit kvalitu vašich aplikací. Vývoj zaměřený na testování je definován následujícím životním cyklem:
- Přidejte test.
- Spusťte všechny své testy a sledujte, jak nový test selhává.
- Implementujte kód.
- Spusťte všechny své testy a sledujte, jak nový test uspěl.
- Refaktorujte kód.
Obrázek 1 ukazuje tento životní cyklus TDD.

Psaní testů před psaním kódu má dvojí účel. Nejprve vás to donutí přemýšlet o obchodním problému, který se snažíte vyřešit. Například, jak by se měly chovat úspěšné scénáře? Jaké podmínky by měly selhat? Jak by měli selhat? Zadruhé, testování vám nejprve dá větší důvěru ve vaše testy. Kdykoli píšu testy po napsání kódu, vždy je musím rozbít, abych se ujistil, že skutečně chytají chyby. Psaní testů se nejprve vyhne tomuto dalšímu kroku.
Psaní testů pro šťastnou cestu je obvykle snadné: S dobrým vstupem by třída měla vrátit deterministickou odpověď. Ale psaní negativních (nebo neúspěšných) testovacích případů, zejména pro složité komponenty, může být komplikovanější.
Jako příklad zvažte psaní testů pro úložiště databáze. Na šťastné cestě vložíme záznam do databáze a přijmeme zpět vytvořený objekt, včetně všech vygenerovaných klíčů. Ve skutečnosti musíme také zvážit možnost konfliktu, jako je vložení záznamu s jedinečnou hodnotou sloupce, která je již držena jiným záznamem. Co se dále stane, když se úložiště nemůže připojit k databázi, snad proto, že se změnilo uživatelské jméno nebo heslo? Co se stane, když dojde k chybě sítě při přenosu? Co se stane, když se požadavek nedokončí ve stanoveném limitu časového limitu?
Chcete-li vytvořit robustní komponentu, musíte zvážit všechny pravděpodobné a nepravděpodobné scénáře, vyvinout pro ně testy a napsat svůj kód tak, aby vyhovoval těmto testům. Později v článku se podíváme na strategie pro vytváření různých scénářů selhání spolu s některými novými funkcemi v JUnit 5, které vám mohou tyto scénáře pomoci otestovat.
Přijetí JUnit 5
Pokud JUnit používáte nějakou dobu, některé změny v JUnit 5 budou úpravou. Zde je souhrn na vysoké úrovni, co se mezi těmito dvěma verzemi liší:
- JUnit 5 je nyní zabalen v
org.junit.jupiter
skupina, která mění způsob, jakým ji zahrnete do svých projektů Maven a Gradle. - JUnit 4 vyžadoval minimální JDK 5 JDK; JUnit 5 vyžaduje minimálně 8 JDK.
- JUnit 4's
@Před
,@Před hodinou
,@Po
, a@Po hodině
poznámky byly nahrazeny@ Předtím každý
,@BeforeAll
,@AfterEach
, a@Po všem
, resp. - JUnit 4's
@Ignorovat
anotace byla nahrazena@ Zakázáno
anotace. - The
@Kategorie
anotace byla nahrazena@Štítek
anotace. - JUnit 5 přidává novou sadu metod tvrzení.
- Běžci byly nahrazeny rozšířeními, s novým API pro implementátory rozšíření.
- JUnit 5 zavádí předpoklady, které zastaví provádění testu.
- JUnit 5 podporuje vnořené a dynamické testovací třídy.
Většinu těchto nových funkcí prozkoumáme v tomto článku.
Testování jednotky pomocí JUnit 5
Začněme jednoduše s příkladem end-to-end konfigurace projektu pro použití JUnit 5 pro test jednotky. Výpis 1 ukazuje a MathTools
třída, jejíž metoda převede čitatele a jmenovatele na a dvojnásobek
.
Výpis 1. Příklad projektu JUnit 5 (MathTools.java)
balíček com.javaworld.geekcap.math; public class MathTools {public static double convertToDecimal (int čitatel, int denominator) {if (denominator == 0) {throw new IllegalArgumentException ("Denominator must not be 0"); } návratový (dvojitý) čitatel / (dvojitý) jmenovatel; }}
Máme dva primární scénáře pro testování MathTools
třída a její metoda:
- A platný test, ve kterém předáme nenulová celá čísla pro čitatele a jmenovatele.
- A scénář selhání, ve kterém předáme nulovou hodnotu pro jmenovatele.
Výpis 2 zobrazuje testovací třídu JUnit 5 pro testování těchto dvou scénářů.
Výpis 2. Testovací třída JUnit 5 (MathToolsTest.java)
balíček com.javaworld.geekcap.math; import java.lang.IllegalArgumentException; importovat org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; třída MathToolsTest {@Test void testConvertToDecimalSuccess () {double result = MathTools.convertToDecimal (3, 4); Assertions.assertEquals (0,75, výsledek); } @Test void testConvertToDecimalInvalidDenominator () {Assertions.assertThrows (IllegalArgumentException.class, () -> MathTools.convertToDecimal (3, 0)); }}
V seznamu 2 je testConvertToDecimalInvalidDenominator
metoda provede MathTools :: convertToDecimal
metoda uvnitř prosazovatVrhá
volání. První argument je očekávaný typ výjimky, která má být vyvolána. Druhým argumentem je funkce, která vyvolá tuto výjimku. The prosazovat
metoda provede funkci a ověří, že je vyvolán očekávaný typ výjimky.
Třída Assertions a její metody
Theorg.junit.jupiter.api.Test
anotace označuje zkušební metodu. Všimněte si, že @Test
anotace nyní pochází z balíčku JUnit 5 Jupiter API namísto JUnit 4 org.junit
balík. The testConvertToDecimalSuccess
metoda nejprve provede MathTools :: convertToDecimal
metoda s čitatelem 3 a jmenovatelem 4, pak tvrdí, že výsledek je roven 0,75. The org.junit.jupiter.api. tvrzení
třída poskytuje sadu statický
metody pro porovnání skutečných a očekávaných výsledků. The Tvrzení
třída má následující metody, které pokrývají většinu primitivních datových typů:
assertArrayEquals
porovnává obsah skutečného pole s očekávaným.assertEquals
porovnává skutečnou hodnotu s očekávanou hodnotou.assertNotEquals
porovná dvě hodnoty, aby ověřil, že nejsou stejné.tvrdit Pravda
ověřuje, že zadaná hodnota je pravdivá.assertFalse
ověřuje, že zadaná hodnota je nepravdivá.assertLinesMatch
porovnává dva seznamyTětiva
s.assertNull
ověřuje, že zadaná hodnota má hodnotu null.assertNotNull
ověřuje, že zadaná hodnota není null.tvrditStejně
ověřuje, že dvě hodnoty odkazují na stejný objekt.assertNotSame
ověřuje, že dvě hodnoty neodkazují na stejný objekt.prosazovatVrhá
ověřuje, že provedení metody vyvolá očekávanou výjimku (můžete to vidět vtestConvertToDecimalInvalidDenominator
příklad výše).assertTimeout
ověřuje, že se zadaná funkce dokončí v rámci zadaného časového limitu.assertTimeout Preventivně
ověřuje, že zadaná funkce se dokončí v rámci zadaného časového limitu, ale jakmile je časový limit dosažen, zabije provedení funkce.
Pokud některá z těchto metod tvrzení selže, je test jednotky označen jako neúspěšný. Toto oznámení o selhání se při spuštění testu zapíše na obrazovku a poté se uloží do souboru zprávy.
Použití delty s assertEquals
Při použití plovák
a dvojnásobek
hodnoty v an assertEquals
, můžete také určit a delta
což představuje hranici rozdílu mezi těmito dvěma. V našem příkladu jsme mohli přidat deltu 0,001, v případě, že 0,75 byla ve skutečnosti vrácena jako 0,750001.
Analýza výsledků testu
Kromě ověření hodnoty nebo chování, tvrdit
metody mohou také přijmout textový popis chyby, který vám pomůže diagnostikovat selhání. Například:
Assertions.assertEquals (0,75, výsledek, "Hodnota MathTools :: convertToDecimal nevrátila správnou hodnotu 0,75 pro 3/4"); Assertions.assertEquals (0,75, result, () -> "Hodnota MathTools :: convertToDecimal nevrátila správnou hodnotu 0,75 pro 3/4");
Výstup zobrazí očekávanou hodnotu 0,75 a skutečnou hodnotu. Zobrazí také zadanou zprávu, která vám pomůže pochopit kontext chyby. Rozdíl mezi těmito dvěma variantami spočívá v tom, že první vždy vytvoří zprávu, i když se nezobrazí, zatímco druhá vytvoří zprávu pouze v případě, že tvrzení selže. V tomto případě je konstrukce zprávy triviální, takže na tom nezáleží. Přesto není nutné sestavit chybovou zprávu pro test, který projde, takže je obvykle osvědčeným postupem použít druhý styl.
Nakonec, pokud používáte IDE jako IntelliJ ke spuštění testů, každá testovací metoda se zobrazí podle názvu metody. To je v pořádku, pokud jsou vaše názvy metod čitelné, ale můžete také přidat a @DisplayName
anotace k vašim testovacím metodám pro lepší identifikaci testů:
@Test @DisplayName ("Testovat úspěšnou desetinnou konverzi") void testConvertToDecimalSuccess () {double result = MathTools.convertToDecimal (3, 4); Assertions.assertEquals (0,751, výsledek); }
Probíhá test jednotky
Chcete-li spustit testy JUnit 5 z projektu Maven, musíte zahrnout maven-surefire-plugin
v Maven pom.xml
soubor a přidat novou závislost. Výpis 3 ukazuje pom.xml
soubor pro tento projekt.
Výpis 3. Maven pom.xml pro ukázkový projekt JUnit 5
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 test junit-jupiter 5.6.0
JUnit 5 závislostí
JUnit 5 balí své komponenty do org.junit.jupiter
skupinu a musíme přidat junit-jupiter
artefakt, což je artefakt agregátoru, který importuje následující závislosti:
junit-jupiter-api
definuje API pro psaní testů a rozšíření.junit-jupiter-engine
je implementace testovacího stroje, která spouští jednotkové testy.junit-jupiter-params
poskytuje podporu pro parametrizované testy.
Dále musíme přidat maven-surefire-plugin
vytvořte modul plug-in, aby bylo možné spustit testy.
Nakonec nezapomeňte zahrnout maven-compiler-plugin
s verzí Java 8 nebo novější, takže budete moci používat funkce Java 8 jako lambdas.
Spusť to!
Pomocí následujícího příkazu spusťte testovací třídu z vašeho IDE nebo z Maven:
mvn čistý test
Pokud jste úspěšní, měli byste vidět výstup podobný tomuto:
[INFO] ----------------------------------------------- -------- [INFO] TESTY [INFO] ----------------------------------- -------------------- [INFO] Spuštění com.javaworld.geekcap.math.MathToolsTest [INFO] Spuštění testů: 2, Selhání: 0, Chyby: 0, Přeskočeno : 0, Uplynulý čas: 0,04 s - v com.javaworld.geekcap.math.MathToolsTest [INFO] [INFO] Výsledky: [INFO] [INFO] Provedení testů: 2, Poruchy: 0, Chyby: 0, Přeskočeno: 0 [ INFO] [INFO] --------------------------------------------- --------------------------- [INFO] BUILD SUCCESS [INFO] --------------- -------------------------------------------------- ------- [INFO] Celkový čas: 3,832 s [INFO] Dokončeno: 2020-02-16T08: 21: 15-05: 00 [INFO] ------------- -------------------------------------------------- ---------