JUnit 5 a Kotlin Developers számára

1. Bemutatkozás

Az újonnan megjelent JUnit 5 a Java jól ismert tesztelési keretrendszerének következő verziója. Ez a verzió számos a Java 8-ban bevezetett funkciókat kifejezetten megcélzó funkciók - elsősorban a lambda kifejezések használatára épül.

Ebben a rövid cikkben megmutatjuk, hogy milyen jól működik ugyanaz az eszköz a Kotlin nyelvvel dolgozik.

2. Egyszerű JUnit 5 tesztek

A legegyszerűbb, hogy a Kotlinban írt JUnit 5 teszt pontosan úgy működik, ahogyan az várható volt. Tesztosztályt írunk, a vizsgálati módszereket a @Teszt megjegyzés, írja meg kódunkat és hajtsa végre az állításokat:

class CalculatorTest {private val calculator = Calculator () @Test fun whenAdding1and3_thenAnswerIs4 () {Assertions.assertEquals (4, calculator.add (1, 3))}}

Itt minden a dobozon kívül működik. Használhatjuk a szabványt @Teszt, @BeforeAll, @BeforeEach, @AfterEach, és @Végül annotációk. A tesztosztály mezőivel is pontosan ugyanúgy működhetünk, mint a Java-ban.

Ne feledje, hogy a szükséges import különböző, és tesszükállításokat a Állítások osztály helyett Állítsd osztály. Ez a JUnit 5 standard változása, és nem csak Kotlinra vonatkozik.

Mielőtt továbbmennénk, változtassuk meg a teszt nevét és használjuk backtick azonosítók Kotlinban:

@Test fun "Az 1 és 3 hozzáadásának egyenlőnek kell lennie 4-vel" () {Assertions.assertEquals (4, calculator.add (1, 3))}

Most sokkal olvashatóbb! Kotlinban az összes változót és függvényt deklarálhatjuk a backticks használatával, de normál használat esetén nem ajánlott.

3. Haladó állítások

Az 5. JUnit fejlett állításokat ad hozzá a következőhöz:lambdákkal dolgozik. Ezek ugyanúgy működnek Kotlinban, mint a Java-ban, de a nyelv működése miatt kissé eltérő módon kell kifejezni őket.

3.1. Kivételek érvényesítése

Az 5. JUnit állítással egészíti ki, hogy mikor várható, hogy egy hívás kivételt jelent. Kipróbálhatjuk, hogy egy adott hívás - nem pedig a módszer bármelyik hívása - dobja a várt kivételt. Még magáról a kivételről is állíthatunk.

Java-ban egy lambdát adunk át a hívásnak Assertions.assertThrows. Ugyanezt tesszük Kotlinban is, de megtehetjük tegye a kódot olvashatóbbá blokkot csatolva az állításhívás végéhez:

@Test fun `A nullával osztva dobnia kell a DivideByZeroException` () {val kivétel = Assertions.assertThrows (DivideByZeroException :: class.java) {calculator.divide (5, 0)} Assertions.assertEquals (5, kivétel.számláló)}

Ez a kód pontosan ugyanúgy működik, mint a Java megfelelője, de könnyebben olvasható, mivel nem kell áthaladni a zárójelben lévő lambda mellett, ahol a assertThrows funkció.

3.2. Több állítás

Az 5. JUnit hozzáadja a képességet több állítást végezhet egyszerre, és kiértékeli mindet, és minden hibáról beszámol.

Ez lehetővé teszi, hogy több információt gyűjtsünk egyetlen próbafutás alatt, ahelyett, hogy kénytelenek lennénk egyetlen hibát kijavítani, hogy csak a következőt érjük el. Ehhez felhívjuk Assertions.assertAll, tetszőleges számú lambdát ad át.

Kotlinban, ezt kissé másképp kell kezelnünk. A függvény valójában a varargs típusú paraméter Végrehajtható.

Jelenleg nincs támogatás a lambda funkcionális felületre történő automatikus átküldésére, ezért kézzel kell elvégeznünk:

fun "A szám négyzetének meg kell egyeznie az önmagában megszorzott számmal" () {Assertions.assertAll (Executable {Assertions.assertEquals (1, calculator.square (1))}}, végrehajtható {Assertions.assertEquals (4, számológép) .square (2))}, végrehajtható {Assertions.assertEquals (9, calculator.square (3))})}

3.3. Az igaz és hamis tesztek szállítói

Esetenként szeretnénk tesztelni, hogy egyes hívások a igaz vagy hamis érték. Történelmileg kiszámolnánk ezt az értéket és felhívnánk assertTrue vagy assertFalse adott esetben. Az 5. JUnit lehetővé teszi lambda megadását, amely visszaadja az ellenőrzött értéket.

Kotlin megengedi, hogy áthaladjunk egy lambdában ugyanúgy, ahogy fentebb láttuk a kivételek tesztelésénél. Módszertani hivatkozásokat is átadhatunk. Ez különösen akkor hasznos, ha tesztelünk valamilyen létező objektum visszatérési értékét, amint azt itt használjuk List.isEppt:

A @Test fun `isEmpty értéknek igaznak kell lennie üres listák esetén` () {val list = listOf () Assertions.assertTrue (list :: isEmpty)}

3.4. Hibaüzenetek szállítói

Bizonyos esetekben szeretnénk adja meg saját hibaüzenetünket hogy az alapértelmezett helyett egy állítási hiba esetén jelenjen meg.

Gyakran ezek egyszerű húrok, de néha érdemes olyan sztringet használni, amelynek kiszámítása drága. Az 5. JUnitben megtehetjük adjon meg egy lambdát ennek a húrnak a kiszámításához, és ez csak kudarcra szólított fel ahelyett, hogy előre kiszámolták volna.

Ez segíthet gyorsabban futtassa a teszteket és csökkentse az összeállítási időket. Ez pontosan ugyanúgy működik, mint korábban láttuk:

@Test fun `3 egyenlő 4` () {Assertions.assertEquals (3, 4) {" Három nem egyenlő négy "}}

4. Adatvezérelt tesztek

A JUnit 5 egyik nagy fejlesztése a natív támogatás az adatközpontú tesztekhez. Ezek ugyanolyan jól működnek Kotlinban, és a funkcionális leképezések használata a gyűjteményeken megkönnyítik tesztjeink olvasását és karbantartását.

4.1. TestFactory módszerek

Az adatközpontú tesztek kezelésének legegyszerűbb módja a @TestFactory annotáció. Ez helyettesíti a @Teszt annotáció, és a metódus a DynamicNode példányok - általában hívással jönnek létre DynamicTest.dynamicTest.

Ez pontosan ugyanúgy működik Kotlinban, és mi is megtehetjük tisztábban adja át a lambdát ismét, amint azt korábban láttuk:

@TestFactory fun testSquares () = listOf (DynamicTest.dynamicTest ("amikor 1 ^ 2-t számolok, akkor 1-et kapok") {Assertions.assertEquals (1, calculator.square (1))}, DynamicTest.dynamicTest ("amikor számolok 2 ^ 2, akkor kapok 4 ") {Assertions.assertEquals (4, calculator.square (2))}, DynamicTest.dynamicTest (" amikor 3 ^ 2-t számolok, akkor 9-et kapok ") {Assertions.assertEquals (9, számológép . négyzet (3))})

Pedig ennél jobbat is tudunk tenni. Könnyen megtehetjük a listánkat úgy alakíthatja ki, hogy funkcionális leképezést hajt végre egy egyszerű adatbeviteli listán:

@TestFactory fun testSquares () = listOf (1–1, 2–4, 3–9, 4–16, 5–25) .map {(input, várható) -> DynamicTest.dynamicTest ("amikor $ inputot számolok ^ 2, akkor kapok $ várt ") {Assertions.assertEquals (várható, számológép.négyzet (bemenet))}}

Rögtön könnyebben felvehetünk több tesztesetet az input listába, és ez automatikusan hozzáadja a teszteket.

Azt is megtehetjük hozza létre az input listát osztálymezőként és ossza meg több teszt között:

privát val négyzetek TestData = listOf (1–1, 2–4, 3–9, 4–16, 5–25) 
@TestFactory fun testSquares () = squaresTestData .map {(input, várható) -> DynamicTest.dynamicTest ("amikor kiszámítom a $ input ^ 2 értéket, akkor megkapom a $ vártat") {Assertions.assertEquals (várható, számológép.square (input) )}}
@TestFactory fun testSquareRoots () = squaresTestData .map {(várható, bemenet) -> DynamicTest.dynamicTest ("amikor kiszámítom a $ input négyzetgyökét, akkor $ várt leszek") {Assertions.assertEquals (várható, calculator.squareRoot ( bemenet))}}

4.2. Paraméteres tesztek

Vannak az 5. JUnit kísérleti kiterjesztései hogy megkönnyítsék a paraméterezett tesztek írását. Ezeket a @ParameterizedTest kommentár a org.junit.jupiter: junit-jupiter-params függőség:

 org.junit.jupiter junit-jupiter-params 5.0.0 

A legújabb verzió megtalálható a Maven Central oldalon.

A @MethodSource az annotáció lehetővé teszi számunkra, hogy állítson elő tesztparamétereket statikus függvény meghívásával amely ugyanabban az osztályban lakik, mint a teszt. Ez lehetséges, de nem nyilvánvaló Kotlinban. Nekünk kell használja a @JvmStatic annotáció a társobjektum:

@ParameterizedTest @MethodSource ("négyzetek") szórakoztató testSquares (input: Int, várható: Int) {Assertions.assertEquals (várható, input * input)} társobjektum {@JvmStatic fun squares () = listOf (Arguments.of (1, 1), érvek (2, 4))}

Ez azt is jelenti, hogy a paraméterek előállítására használt módszereknek mind együtt kell lenniük, mivel csak egyetlenegyünk lehet társ tárgy osztályonként.

A paraméterezett tesztek összes többi módja ugyanúgy működik Kotlinban, mint a Java-ban. @CsvSource itt külön említésre méltó, mivel ezt a helyett használhatjuk @MethodSource egyszerű tesztadatokhoz, hogy tesztjeink olvashatóbbak legyenek:

@ParameterizedTest @CsvSource ("1, 1", "2, 4", "3, 9") szórakoztató testSquares (bemenet: Int, várható: Int) {Assertions.assertEquals (várható, input * input)}

5. Címkézett tesztek

A kotlin nyelv jelenleg nem teszi lehetővé az ismételt megjegyzéseket osztályokról és módszerekről. Ez kissé bőbeszédesebbé teszi a címkék használatát, ahogyan nekünk kötelező tekerje be őket a @Tags kommentár:

@Tags (Tag ("lassú"), Tag ("logaritmus")) @Test fun "A 8/2-es bázisra való bejelentkezésnek 3-nak kell lennie" () {Assertions.assertEquals (3.0, calculator.log (2, 8) )}

Erre a Java 7-ben is szükség van, és a JUnit 5 már teljes mértékben támogatja.

6. Összefoglalás

A JUnit 5 néhány hatékony tesztelő eszközt kínál, amelyeket használhatunk. Ezek szinte mind tökéletesen működnek a Kotlin nyelvvel, bár egyes esetekben kissé eltérő szintaxissal rendelkeznek, mint amit a Java megfelelőiben látunk.

A szintaxis ezen változásai azonban gyakran könnyebben olvashatók és kezelhetők a Kotlin használatakor.

Példák ezekre a funkciókra a GitHub oldalon találhatók.