Útmutató a JUnit 5 paraméterezett tesztjeihez

1. Áttekintés

A JUnit 5, a JUnit következő generációja új és fényes funkciókkal segíti a fejlesztői tesztek megírását.

Az egyik ilyen tulajdonság az oarameterizált tesztek. Ez a funkció lehetővé teszi számunkra, hogy végezzen egyetlen vizsgálati módszert többször, különböző paraméterekkel.

Ebben az oktatóanyagban a paraméterezett teszteket vizsgáljuk meg alaposan, ezért kezdjük!

2. Függőségek

A JUnit 5 paraméterezett tesztjeinek használatához importálnunk kell a junit-jupiter-params műtárgy a JUnit Platform-tól. Ez azt jelenti, hogy a Maven használatakor a következőket adjuk hozzá pom.xml:

 org.junit.jupiter junit-jupiter-params 5.7.0 teszt 

Ezenkívül a Gradle használatakor kicsit másképp fogjuk megadni:

testCompile ("org.junit.jupiter: junit-jupiter-params: 5.7.0")

3. Első benyomás

Tegyük fel, hogy van egy létező segédfunkciónk, és szeretnénk biztosak lenni a viselkedésében:

public class Numbers {nyilvános statikus logikai isOdd (int szám) {visszatérési szám% 2! = 0; }}

A paraméterezett tesztek olyanok, mint a többi teszt, kivéve, hogy hozzáadjuk a @ParameterizedTest kommentár:

@ParameterizedTest @ValueSource (ints = {1, 3, 5, -3, 15, Egész.MAX_VALUE}) // hat szám érvénytelen isOdd_ShouldReturnTrueForOddNumbers (int szám) {assertTrue (Számok.isOdd (szám)); }

A JUnit 5 tesztfutó végrehajtja ezt a fenti tesztet - és ennek következtében a isOdd módszer - hatszor. És minden alkalommal más és más értéket rendel hozzá @ValueSource tömb a szám method paraméter.

Tehát ez a példa két dolgot mutat be, amelyre szükségünk van egy paraméterezett teszthez:

  • érvek forrása, an int tömb, ebben az esetben
  • a hozzáférés módja, ebben az esetben a szám paraméter

Van még egy dolog, ami nem nyilvánvaló ebben a példában, ezért maradjon velünk.

4. Argumentumforrások

Amint azt már tudnunk kell, egy paraméterezett teszt ugyanazt a tesztet többször, különböző argumentumokkal hajtja végre.

Remélhetőleg nem csak a számokat tehetjük meg - hát vizsgáljuk meg!

4.1. Egyszerű értékek

A ... val @ValueSource annotációval, a szó szerinti értékek tömbjét átadhatjuk a vizsgálati módszernek.

Tegyük fel például, hogy tesztelni fogjuk egyszerűségünket isBlank módszer:

public class Strings {public static logikai isBlank (String input) return input == null}

Arra számítunk, hogy ez a módszer visszatér igaz mert nulla üres húrokhoz. Tehát írhatunk egy paraméterezett tesztet, amely az alábbiak szerint állíthatja ezt a viselkedést:

@ParameterizedTest @ValueSource (stringek = {"", ""}}) void isBlank_ShouldReturnTrueForNullOrBlankStrings (String input) {assertTrue (Strings.isBlank (input)); } 

Mint láthatjuk, a JUnit kétszer lefuttatja ezt a tesztet, és minden alkalommal hozzárendel egy argumentumot a tömbből a method paraméterhez.

Az értékforrások egyik korlátja, hogy csak a következő típusokat támogatják:

  • rövid (a ... val rövidnadrág tulajdonság)
  • byte (a ... val bájtokat tulajdonság)
  • int (a ... val ints tulajdonság)
  • hosszú (a ... val vágyakozik tulajdonság)
  • úszó (a ... val lebeg tulajdonság)
  • kettős (a ... val duplázik tulajdonság)
  • char (a ... val karakterek tulajdonság)
  • java.lang.String (a ... val húrok tulajdonság)
  • java.lang.Osztály (a ... val osztályok tulajdonság)

Is, minden alkalommal csak egy argumentumot adhatunk át a vizsgálati módszerhez.

És mielőtt tovább ment volna, észrevette-e valaki, hogy nem mentünk át nulla érvként? Ez egy másik korlátozás: Nem mehetünk át nulla keresztül a @ValueSource, még arra is Húr és Osztály!

4.2. Null és üres értékek

A JUnit 5.4-től kezdve egyetlenet is átadhatunk nulla értéket egy paraméterezett vizsgálati módszerhez @NullSource:

@ParameterizedTest @NullSource void isBlank_ShouldReturnTrueForNullInputs (String input) {assertTrue (Strings.isBlank (input)); }

Mivel a primitív adattípusok nem fogadhatók el nulla értékeket, nem használhatjuk a @NullSource primitív érvekért.

Hasonló módon adhatunk át üres értékeket a @EmptySource kommentár:

@ParameterizedTest @EmptySource void isBlank_ShouldReturnTrueForEmptyStrings (String input) {assertTrue (Strings.isBlank (input)); }

@EmptySource egyetlen üres argumentumot ad át az annotált metódusnak.

Mert Húr argumentumok esetén az átadott érték olyan egyszerű lenne, mint egy üres Húr. Sőt, ez a paraméterforrás üres értékeket adhat a Gyűjtemény típusok és tömbök.

Annak érdekében, hogy mindkettőnek megfeleljen nulla és üres értékek, használhatjuk a komponáltakat @NullAndEmptySource kommentár:

@ParameterizedTest @NullAndEmptySource void isBlank_ShouldReturnTrueForNullAndEmptyStrings (String input) {assertTrue (Strings.isBlank (input)); }

Mint a @EmptySource, az összeállított kommentár a következőhöz működik: Húrs,Gyűjteménys, és tömbök.

Annak érdekében, hogy még néhány üres karakterlánc variációt átadjunk a paraméterezett tesztnek, kombinálhatjuk @ValueSource, @NullSource és @EmptySource együtt:

@ParameterizedTest @NullAndEmptySource @ValueSource (string = {"", "\ t", "\ n"}) void isBlank_ShouldReturnTrueForAllTypesOfBlankStrings (String input) {assertTrue (Strings.isBlank (input); }

4.3. Enum

Annak érdekében, hogy egy felsorolásban szereplő értékekkel különböző tesztet fussunk, használhatjuk a @EnumSource annotáció.

Azt állíthatjuk például, hogy az összes havi szám 1 és 12 között van:

@ParameterizedTest @EnumSource (Month.class) // mind a 12 hónap átengedése void getValueForAMonth_IsAlwaysBetweenOneAndTwelve (Month month) {int monthNumber = month.getValue (); assertTrue (monthNumber> = 1 && monthNumber <= 12); }

Vagy kiszűrhetünk néhány hónapot a nevek tulajdonság.

Mit szólnál ahhoz, ha azt állítanád, hogy április, szeptember, június és november 30 napos:

@ParameterizedTest @EnumSource (value = Month.class, names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER"}) void someMonths_Are30DaysLong (Month month) {final boolean isALeapYear = false; assertEquals (30, hónap.hossz (isALeapYear)); }

Alapértelmezés szerint a nevek csak az egyező enum értékeket fogja megtartani. Ezt megfordíthatjuk a mód tulajdonít neki KIZÁRNI:

@ParameterizedTest @EnumSource (érték = Month.class, names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER", "FEBRUARY"}, mode = EnumSource.Mode.EXCLUDE) void paitsiFourMonths_OthersAre31DaysLong végső logikai érték isALeapYear = hamis; assertEquals (31, hónap.hossz (isALeapYear)); }

A szó szerinti húrok mellett szabályos kifejezést adhatunk át a nevek tulajdonság:

@ParameterizedTest @EnumSource (érték = Hónap.osztály, nevek = ". + BER", mód = EnumSource.Mode.MATCH_ANY) érvénytelen négy Hónap_AreEndingWithBer (Hónap hónap) {EnumSet hónap = EnumSet.of (Hónap.SEPTEMBER, Hónap.OCTOBER, .NOVEMBER, hónap.DECEMBER); assertTrue (hónapok.tartalmaz (hónap)); }

Egészen hasonló @ValueSource, @EnumSource csak akkor alkalmazható, ha tesztfuttatásonként csak egy argumentumot adunk át.

4.4. CSV Literals

Tegyük fel, hogy meg fogunk győződni arról, hogy a toUpperCase () módszer től Húr generálja a várható nagybetűs értéket. @ValueSource nem lesz elég.

Paraméteres teszt írásához az ilyen forgatókönyvekhez meg kell tennünk:

  • Át egy bemeneti érték és an várható érték a vizsgálati módszerhez
  • Számítsa ki a tényleges eredmény azokkal a bemeneti értékekkel
  • Állítsd a tényleges érték a várható értékkel

Szükségünk van olyan argumentumforrásokra, amelyek képesek több argumentum átadására. A @CsvSource az egyik ilyen forrás:

@ParameterizedTest @CsvSource ({"teszt, TEST", "tEst, TEST", "Java, JAVA"}) void toUpperCase_ShouldGenerateTheExpectedUppercaseValue (String input, String várható) {String actualValue = input.toUpperCase (); assertEquals (várható, tényleges érték); }

A @CsvSource vesszővel elválasztott értékek tömbjét fogadja el, és minden tömbbejegyzés megfelel egy CSV fájl sorának.

Ez a forrás minden alkalommal egy tömb bejegyzést vesz fel, vesszővel osztja fel és mindegyik tömböt külön paraméterként továbbítja az annotált vizsgálati módszerhez. Alapértelmezés szerint a vessző az oszlopelválasztó, de testre szabhatjuk a határoló tulajdonság:

@ParameterizedTest @CsvSource (value = {"test: test", "tEst: test", "Java: java"}, delimiter = ':') void toLowerCase_ShouldGenerateTheExpectedLowercaseValue (String bevitel, String várható) {String actualValue = input.toLowerCase ( ); assertEquals (várható, tényleges érték); }

Most ez egy kettőspont-külön érték, még mindig CSV!

4.5. CSV-fájlok

Ahelyett, hogy átadnánk a CSV értékeket a kódban, hivatkozhatunk egy tényleges CSV fájlra.

Például használhatunk egy CSV fájlt, például:

bemenet, várható teszt, TEST tEst, TEST Java, JAVA

Betölthetjük a CSV fájlt és hagyja figyelmen kívül a fejléc oszlopot val vel @CsvFileSource:

@ParameterizedTest @CsvFileSource (erőforrások = "/data.csv", numLinesToSkip = 1) void toUpperCase_ShouldGenerateTheExpectedUppercaseValueCSVFile (String input, String várható) {String actualValue = input.toUpperCase (); assertEquals (várható, tényleges érték); }

A erőforrások attribútum az elolvasandó osztályútvonal CSV fájl erőforrásait jelöli. Több fájlt is átadhatunk neki.

A numLinesToSkip attribútum a CSV fájlok olvasásakor kihagyandó sorok számát jelenti. Alapértelmezés szerint, @CsvFileSource nem hagy ki egyetlen sort sem, de ez a szolgáltatás általában hasznos a fejlécsorok kihagyásához, mint itt tettük.

Akárcsak az egyszerű @CsvSource, az elválasztó testreszabható a határoló tulajdonság.

Az oszlopelválasztón kívül:

  • A vonalelválasztó testreszabható a lineSeparator attribútum - új sor az alapértelmezett érték
  • A fájlkódolás testreszabható a kódolás attribútum - az UTF-8 az alapértelmezett érték

4.6. Módszer

Az eddig tárgyalt érvelési források kissé egyszerűek és egy korlátot mutatnak: Nehéz vagy lehetetlen átadni összetett objektumokat ezek használatával!

Az egyik megközelítés összetettebb érvek megadása egy módszer használata argumentumforrásként.

Teszteljük a isBlank módszer a @MethodSource:

@ParameterizedTest @MethodSource ("nodrošinātStringsForIsBlank") void isBlank_ShouldReturnTrueForNullOrBlankStrings (Karakterlánc-bemenet, logikai elvárt) {assertEquals (várható, Strings.isBlank (input)); }

A név, amelyet ellátunk @MethodSource meg kell egyeznie egy meglévő módszerrel.

Tehát írjuk legközelebb provideStringsForIsBlank, a statikus metódus, amely a Folyam nak,-nek Érvs:

privát statikus adatfolyam biztosítja hamis) ); }

Itt szó szerint viszonzunk egy érvelést, de ez nem szigorú követelmény. Például, bármilyen más gyűjteményszerű felületet visszaadhatunk Lista.

Ha teszt meghívásonként csak egy argumentumot fogunk megadni, akkor nem szükséges a Érvek absztrakció:

@ParameterizedTest @MethodSource // hmm, nincs módszer neve ... void isBlank_ShouldReturnTrueForNullOrBlankStringsOneArgument (String input) {assertTrue (Strings.isBlank (input)); } privát statikus adatfolyam isBlank_ShouldReturnTrueForNullOrBlankStringsOneArgument () {return Stream.of (null, "", ""); }

Amikor nem adunk nevet a @MethodSource, A JUnit megkeresi a vizsgálati módszerrel megegyező nevű forrásmódszert.

Néha hasznos megosztani az érveket a különböző tesztosztályok között. Ezekben az esetekben az aktuális osztályon kívüli forrásmódszerre hivatkozhatunk teljesen minősített nevével:

class StringsUnitTest {@ParameterizedTest @MethodSource ("com.baeldung.parameterized.StringParams # blankStrings") void isBlank_ShouldReturnTrueForNullOrBlankStringsExternalSource (String input) {assertTrank (Strings.rue) }} public class StringParams {static Stream blankStrings () {return Stream.of (null, "", ""); }}

Használni a FQN # methodName formátumban hivatkozhatunk egy külső statikus módszerre.

4.7. Egyéni argumentumszolgáltató

A teszt argumentumok átadásának másik fejlett megközelítése az úgynevezett felület egyedi megvalósításának használata Szolgáltató:

class BlankStringsArgumentsProvider megvalósítja az ArgumentsProvider {@Orride public Stream provideArguments (ExtensionContext context) {return Stream.of (Arguments.of ((String) null), Arguments.of (""), Arguments.of ("")); }}

Ezután feljegyezhetjük tesztünket a @ArgumentsSource jelölés az egyéni szolgáltató használatához:

@ParameterizedTest @ArgumentsSource (BlankStringsArgumentsProvider.class) void isBlank_ShouldReturnTrueForNullOrBlankStringsArgProvider (String input) {assertTrue (Strings.isBlank (input)); }

Tegyük az egyéni szolgáltatót kellemesebb API-ként történő használatra, egyedi jelölésekkel!

4.8. Egyéni kommentár

Mi lenne, ha a teszt argumentumokat statikus változóból töltené be? Valami hasonló:

statikus adatfolyam argumentumok = Stream.of (Az Arguments.of (null, true), // null karakterláncokat üresnek kell tekinteni. Arguments.of ("", true), Arguments.of ("", true), Arguments.of (" nem üres ", hamis)); @ParameterizedTest @VariableSource ("argumentumok") void isBlank_ShouldReturnTrueForNullOrBlankStringsVariableSource (Stringbevitel, logikai elvárt) {assertEquals (várható, Strings.isBlank (input)); }

Tulajdonképpen, Az 5. JUnit ezt nem biztosítja! A saját megoldást azonban guríthatjuk.

Először is létrehozhatunk egy kommentárt:

@Documented @Target (ElementType.METHOD) @Retention (RetentionPolicy.RUNTIME) @ArgumentsSource (VariableArgumentsProvider.class) public @interface VariableSource {/ ** * A statikus változó neve * / String érték (); }

Akkor muszáj valahogy fogyasztja az annotációt részletek és adjon meg tesztérveket. A JUnit 5 két absztrakciót biztosít a két dolog eléréséhez:

  • AnnotationFogyasztó hogy felhasználják az annotáció részleteit
  • ArgumentProvider tesztérvek megadására

Tehát legközelebb el kell készítenünk a VariableArgumentsProvider osztály a megadott statikus változóból kiolvasva adja vissza az értékét teszt argumentumként:

class VariableArgumentsProvider megvalósítja az ArgumentsProvider, AnnotationConsumer {private String változóNév; @Orride public Stream provideArguments (ExtensionContext context) {return context.getTestClass () .map (this :: getField) .map (this :: getValue) .orElseThrow (() -> new IllegalArgumentException ("Nem sikerült betölteni a teszt argumentumokat") ); } @Orride public void accept (VariableSource variableSource) {változóNév = változóForrás.érték (); } privát mező getField (Class clazz) {try {return clazz.getDeclaredField (változóNév); } catch (e kivétel) {return null; }} @SuppressWarnings ("bejelöletlen") privát adatfolyam getValue (mező mező) {Object value = null; próbáld ki a {value = field.get (null) parancsot; } catch (kivétel figyelmen kívül hagyva) {} return value == null? null: (Stream) érték; }}

És varázslatként működik!

5. Argumentkonverzió

5.1. Implicit konverzió

Írjuk újra az egyiket @EnumTests egy @ -valCsvSource:

@ParameterizedTest @CsvSource ({"APRIL", "JUNE", "SZEPTEMBER", "NOVEMBER"}) // Pssing karakterláncok érvénytelenítenek néhány hónapot_Are30DaysLongCsv (hónap hónap) {final logikai isALeapYear = false; assertEquals (30, hónap.hossz (isALeapYear)); }

Ennek nem kellene működnie, igaz? De valahogy mégis!

Tehát az 5. JUnit átalakítja a Húr argumentumokat a megadott enum típushoz. Az ilyen felhasználási esetek támogatásához a JUnit Jupiter számos beépített implicit típusú konvertert biztosít.

Az átalakítási folyamat az egyes módszerparaméterek deklarált típusától függ. Az implicit konverzióval konvertálható a Húr példányok a következő típusokhoz:

  • UUID
  • Területi beállítás
  • LocalDate, LocalTime, LocalDateTime, Year, Month stb.
  • File és Pálya
  • URL és URI
  • Enum alosztályok

5.2. Kifejezett megtérés

Néha egyedi és explicit átalakítót kell adnunk az argumentumokhoz.

Tegyük fel, hogy a karakterláncokat a éééé / hh / nnformátum LocalDate példányok. Először is meg kell valósítanunk a ArgumentConverter felület:

osztály A SlashyDateConverter megvalósítja az ArgumentConverter {@Orride public Object convert (Object source, ParameterContext context) dobja az ArgumentConversionException {if (! (forrás példánya String)) {dobja új IllegalArgumentException ("Az argumentumnak karakterlánc legyen:" + forrás); } próbáld ki a {String [] parts = ((String) forrás) .split ("/"); int év = Integer.parseInt (részek [0]); int hónap = Integer.parseInt (részek [1]); int nap = Integer.parseInt (részek [2]); return LocalDate.of (év, hónap, nap); } catch (e kivétel) {dobjon új IllegalArgumentException ("Nem sikerült átalakítani", e); }}}

Ezután utalnunk kell a konverterre a @ConvertWith kommentár:

@ParameterizedTest @CsvSource ({"2018/12 / 25,2018", "2019/02 / 11,2019"}) void getYear_ShouldWorkAsExpected (@ConvertWith (SlashyDateConverter.class) LocalDate date, int várható) {assertEquals (várható, dátum. getYear ()); }

6. Argumentum-hozzáférés

Alapértelmezés szerint a paraméterezett teszt minden argumentuma egyetlen módszer paraméternek felel meg. Következésképpen, amikor egy maroknyi argumentumot átadunk egy argumentumforrásnak, a vizsgálati módszer aláírása nagyon nagy és rendetlen lesz.

A probléma megoldásának egyik megközelítése az összes átadott argumentum összefoglalása a ArgumentsAccessor és beolvassa az argumentumokat index és típus szerint.

Például vegyük figyelembe a sajátunkat Személy osztály:

osztály Személy {String keresztnév; String middleName; Karakterlánc vezetéknév; // konstruktor public String fullName () {if (középnév == null || középnév.trim (). isEmpty ()) {return String.format ("% s% s", keresztnév, vezetéknév); } return String.format ("% s% s% s", keresztnév, középnév, vezetéknév); }}

Ezután annak tesztelése érdekében teljes név() módszerrel négy érvet adunk át: keresztnév középső név vezetéknév, és a várható fullName. Használhatjuk a ArgumentsAccessor a teszt argumentumok lekérése ahelyett, hogy metódus paraméterként deklarálná őket:

@ParameterizedTest @CsvSource ({"Isaac ,, Newton, Isaac Newton", "Charles, Robert, Darwin, Charles Robert Darwin"}) void fullName_ShouldGenerateTheExpectedFullName (ArgumentsAccessor argumentsAccessor) {String firstName = argumentsAccessor.getString (0); String middleName = (Karakterlánc) argumentsAccessor.get (1); Karakterlánc vezetéknév = argumentsAccessor.get (2, String.osztály); Karakterlánc vártFullName = argumentumokAccessor.getString (3); Személy személy = új Személy (keresztnév, középnév, vezetéknév); assertEquals (várhatóFullName, person.fullName ()); }

Itt összesített argumentumot összefoglalunk egy ArgumentsAccessor példányt, majd a tesztmódszer törzsében az összes átadott argumentumot beolvassa az indexével. Amellett, hogy csak hozzáférő, a típuskonverziót a rendszer támogatja kap* mód:

  • getString (index) lekér egy elemet egy adott indexen, és átalakítja Húrtugyanez igaz a primitív típusokra is
  • get (index) egyszerűen lekér egy elemet egy adott indexen, mint egy Tárgy
  • get (index, típus) lekér egy elemet egy adott indexen, és átalakítja az adottra típus

7. Argumentum összesítő

Használni a ArgumentsAccessor az absztrakció a tesztkódot kevésbé olvashatóvá vagy újrafelhasználhatóvá teheti. E problémák megoldása érdekében egyedi és újrafelhasználható összesítőt írhatunk.

Ehhez megvalósítjuk a Argumentumok összesítője felület:

class PersonAggregator implementálja az ArgumentsAggregator {@Orride public Object aggregateArguments (ArgumentsAccessor accessor, ParameterContext context) dobja az ArgumentsAggregationException {return new Person (accessor.getString (1), accessor.getString (2), accessor.getString (3); }}

És akkor hivatkozunk rá a @AggregateWith kommentár:

@ParameterizedTest @CsvSource ({"Isaac Newton, Isaac ,, Newton", "Charles Robert Darwin, Charles, Robert, Darwin"}) void fullName_ShouldGenerateTheExpectedFullName (String vártFullName, @AggregateWith (PersonAggregator.className (PersonFlugEnterName) (personAggregator.ass) person.fullName ()); }

A PersonAggregator az utolsó három érvet veszi fel és példányosítja a Személy osztály belőlük.

8. A megjelenítési nevek testreszabása

Alapértelmezés szerint a paraméterezett teszt megjelenítési neve egy invokációs indexet tartalmaz az a-val együtt Húr az összes elfogadott argumentum ábrázolása, például:

├─ someMonths_Are30DaysLongCsv (hónap) │ │ ├─ [1] ÁPRILIS │ │ ├─ [2] JÚNIUS │ │ ├─ [3] SZEPTEMBER │ │ └─ [4] NOVEMBER

Ezt a kijelzőt azonban a név attribútuma @ParameterizedTest kommentár:

@ParameterizedTest (név = "{index} {0} 30 napos") @EnumSource (érték = Month.class, nevek = {"ÁPRILIS", "JÚNIUS", "SZEPTEMBER", "NOVEMBER"}) void someMonths_Are30DaysLong ( Hónap hónap) {végső logikai isALeapYear = hamis; assertEquals (30, hónap.hossz (isALeapYear)); }

Április 30 napos bizonyára olvashatóbb megjelenítési név:

├─ someHonths_Are30DaysLong (Month) │ │ ├─ APRIL 1 30 napos │ │ ├─ JÚNIUS 2. 30 napos │ │ ├─ SZEPTEMBER 3. 30 nap. NO │ └─ NOVEMBER 4. 30 nap.

A megjelenített név testreszabásakor a következő helyőrzők állnak rendelkezésre:

  • {index} lecserélésre kerül az invokációs indexre - egyszerűen fogalmazva, az első végrehajtás invokációs indexe 1, a másodiké 2, és így tovább
  • {érvek} a teljes, vesszővel elválasztott argumentumlista helyőrzője
  • {0}, {1}, ... az egyes argumentumok helyőrzői

9. Következtetés

Ebben a cikkben a JUnit 5 paraméterezett tesztjeinek anyáit és csavarjait vizsgáltuk.

Megtudtuk, hogy a paraméterezett tesztek két szempontból különböznek a normál tesztektől: azokat a @ParameterizedTest, és forrásra van szükségük a deklarált érveikhez.

Mostanra azt is meg kell tennünk, hogy a JUnit biztosít néhány lehetőséget az argumentumok egyéni céltípusokká alakítására vagy a tesztnevek testreszabására.

Szokás szerint a mintakódok elérhetők a GitHub projektünkön, ezért mindenképpen ellenőrizze!


$config[zx-auto] not found$config[zx-overlay] not found