Sablonok írása tesztesetekhez az 5. JUnit használatával

1. Áttekintés

A JUnit 5 könyvtár számos új funkciót kínál a korábbi verzióihoz képest. Az egyik ilyen jellemző a teszt sablonok. Röviden, a tesztsablonok a JUnit 5 paraméterezett és ismételt tesztjeinek hatékony általánosítását jelentik.

Ebben az oktatóanyagban megtanuljuk, hogyan kell létrehozni egy tesztsablont az 5. JUnit használatával.

2. Maven-függőségek

Kezdjük azzal, hogy hozzáadjuk a függőségeket a sajátunkhoz pom.xml.

Hozzá kell adnunk a fő JUnit 5-öt junit-jupiter-motor függőség:

 org.junit.jupiter junit-jupiter-motor 5.7.0 

Ezen felül hozzá kell adnunk a junit-jupiter-api függőség:

 org.junit.jupiter junit-jupiter-api 5.7.0 

Hasonlóképpen hozzáadhatjuk a szükséges függőségeket is épít.gradle fájl:

testCompile group: 'org.junit.jupiter', név: 'junit-jupiter-engine', verzió: '5.7.0' testCompile group: 'org.junit.jupiter', név: 'junit-jupiter-api', verzió : „5.7.0”

3. A probléma megállapítása

A tesztsablonok megtekintése előtt röviden vessünk egy pillantást a JUnit 5 paraméterezett tesztjeire. A paraméterezett tesztek lehetővé teszik számunkra, hogy különböző paramétereket injektáljunk a vizsgálati módszerbe. Ennek eredményeként mikor paraméterezett tesztek segítségével,egyetlen vizsgálati módszert többször, különböző paraméterekkel hajthatunk végre.

Tegyük fel, hogy most többször szeretnénk futtatni a tesztelési módszerünket - nemcsak különböző paraméterekkel, hanem minden alkalommal más meghívási kontextusban is.

Más szavakkal, azt szeretnénk, ha a tesztmódszert többször is végrehajtanánk, minden egyes meghíváshoz a konfigurációk különböző kombinációit használva mint például:

  • különböző paraméterek felhasználásával
  • a tesztosztály példányának másképp történő előkészítése - vagyis különböző függőségek injektálása a tesztpéldányba
  • a teszt futtatása különböző körülmények között, például az invokációk egy részének engedélyezése / letiltása, ha a környezet „QA
  • más életciklusú visszahívási viselkedéssel fut - talán egy adatbázist szeretnénk felállítani és lebontani az invokációk egy részhalmaza előtt és után

A paraméterezett tesztek használata ebben az esetben gyorsan korlátozottnak bizonyul. Szerencsére a JUnit 5 erőteljes megoldást kínál erre a forgatókönyvre tesztsablonok formájában.

4. Teszt sablonok

Maga a tesztsablon nem teszteset. Ehelyett, ahogy a nevük is sugallja, csak sablonok az adott tesztesetekhez. A paraméterezett és ismételt tesztek erőteljes általánosítása.

A tesztsablonokat egyszer hívják meg minden meghívási környezethez, amelyeket a meghívási környezet szolgáltató (k) bocsátottak rendelkezésre.

Most nézzünk meg egy példát a tesztsablonokra. Amint fentebb megállapítottuk, a fő szereplők a következők:

  • teszt cél módszer
  • teszt sablon módszer
  • egy vagy több, a sablon módszerrel regisztrált meghívási környezet szolgáltató
  • egy vagy több meghívási környezet, amelyet az egyes meghívási környezetszolgáltatók biztosítanak

4.1. A tesztcél módszer

Ebben a példában egy egyszerűt fogunk használni UserIdGeneratorImpl.generate módszer mint teszt célunk.

Határozzuk meg a UserIdGeneratorImpl osztály:

public class UserIdGeneratorImpl implementálja a UserIdGenerator {private boolean isFeatureEnabled; public UserIdGeneratorImpl (logikai isFeatureEnabled) {this.isFeatureEnabled = isFeatureEnabled; } public String generálás (String keresztnév, String vezetéknév) {String kezdetiAndLastName = keresztnév.substring (0, 1) .concat (vezetékNév); a return isFeatureEnabled? "bael" .concat (kezdetiAndLastName): kezdetiAndLastName; }}

A generál módszer, amely a teszt célunk, a keresztnév és vezetéknév paraméterként és felhasználói azonosítót generál. A felhasználói azonosító formátuma változik, attól függően, hogy a funkciókapcsoló engedélyezve van-e vagy sem.

Lássuk, hogyan néz ki ez:

Az adott funkciókapcsoló le van tiltva, amikor a keresztnév = "John" és a vezetéknév = "Smith" Ezután a "JSmith" visszatér

Ezután írjuk meg a teszt sablon módszerét.

4.2. A teszt sablon módszere

Itt van egy teszt sablon a teszt cél módszerünkhöz UserIdGeneratorImpl.generate:

public class UserIdGeneratorImplUnitTest {@TestTemplate @ExtendWith (UserIdGeneratorTestInvocationContextProvider.class) public void whenUserIdRequested_thenUserIdIsReturnedInCorrectFormat (UserIdGeneratorTestCaptorGenerator (UserIdGeneratorTestCaseGenerator) String actualUserId = userIdGenerator.generate (testCase.getFirstName (), testCase.getLastName ()); assertThat (actualUserId) .isEqualTo (testCase.getExpectedUserId ()); }}

Vizsgáljuk meg közelebbről a teszt sablon módszerét.

Mindenekelőtt, létrehozzuk a tesztsablon módszerünket úgy, hogy azt a JUnit 5-el jelöljük @TestTemplate annotáció.

Ezt követően regisztrálunk egy kontextus szolgáltatót, UserIdGeneratorTestInvocationContextProvider,használni a @ExtendWith annotáció. Több kontextus szolgáltatót is regisztrálhatunk a tesztsablonnal. E példa céljából azonban egyetlen szolgáltatót regisztrálunk.

Ezenkívül a sablon módszer megkapja a UserIdGeneratorTestCase paraméterként. Ez egyszerűen egy átfogó osztály a bemenetekre és a teszteset várható eredményére:

public class UserIdGeneratorTestCase {privát logikai isFeatureEnabled; privát karakterlánc keresztnév; privát karakterlánc vezetéknév; privát karakterlánc várhatóUserId; // Normál beállítók és szerelők}

Végül meghívjuk a teszt cél módszerét és azt állítjuk, hogy ez az eredmény a vártnak felel meg

Itt az ideje meghatározni az invokációs kontextus szolgáltatónkat.

4.3. A meghívás kontextusszolgáltatója

Legalább egyet regisztrálnunk kell TestTemplateInvocationContextProvider tesztsablonunkkal. Minden regisztrált TestTemplateInvocationContextProvider biztosítja a Folyam nak,-nek TestTemplateInvocationContext példányok.

Korábban a @ExtendWith annotáció, regisztráltuk UserIdGeneratorTestInvocationContextProvider mint meghívó szolgáltatónk.

Most definiáljuk ezt az osztályt:

public class UserIdGeneratorTestInvocationContextProvider végrehajtja a TestTemplateInvocationContextProvider {// ...}

Meghívási kontextusunk végrehajtja a TestTemplateInvocationContextProvider interfész, amelynek két módszere van:

  • supportTestTemplate
  • provideTestTemplateInvocationContexts

Kezdjük a supportTestTemplate módszer:

@Orride public boolean supportTestTemplate (ExtensionContext extensionContext) {return true; }

A JUnit 5 végrehajtó motor meghívja a supportTestTemplate módszer először érvényesíteni, ha a szolgáltató alkalmazható az adott ExecutionContext. Ebben az esetben egyszerűen visszatérünk igaz.

Most hajtsuk végre a provideTestTemplateInvocationContexts módszer:

@Orride public Stream provideTestTemplateInvocationContexts (ExtensionContext extensionContext) {boolean featureDisabled = false; boolean featureEnabled = true; return Stream.of (featureDisabledContext (new UserIdGeneratorTestCase ("Adott funkciókapcsoló le van tiltva, ha a felhasználó neve John Smith, majd a létrehozott felhasználói azonosító JSmith", featureDisabled, "John", "Smith", "JSmith")), featureEnabledContext (új UserIdGeneratorTestCase (" Adott szolgáltatáskapcsoló engedélyezve, amikor a felhasználó neve John Smith. A létrehozott felhasználói azonosító baelJSmith ", featureEnabled," John "," Smith "," baelJSmith "))); }

A provideTestTemplateInvocationContexts módszer az, hogy a Folyam nak,-nek TestTemplateInvocationContext példányok. Példánkhoz két példányt ad vissza, a metódusok biztosítják featureDisabledContext és featureEnabledContext. Következésképpen a tesztsablonunk kétszer fog futni.

Ezután nézzük meg a kettőt TestTemplateInvocationContext az ilyen módszerekkel visszaadott példányok.

4.4. A meghívási kontextus példányai

Az invokációs kontextusok a TestTemplateInvocationContext interfészt, és hajtsa végre a következő módszereket:

  • getDisplayName - adja meg a teszt megjelenítési nevét
  • getAdditionalExtensions - további meghosszabbításokat adhat vissza az invokációs kontextushoz

Határozzuk meg a featureDisabledContext módszer, amely az első meghívási környezet példányunkat adja vissza:

privát TestTemplateInvocationContext featureDisabledContext (UserIdGeneratorTestCase userIdGeneratorTestCase) {return new TestTemplateInvocationContext () {@Orride public String getDisplayName (int invocationIndex) {return userIdGeneratorTestCase.getDisplayName } @Orride public list getAdditionalExtensions () {return asList (new GenericTypedParameterResolver (userIdGeneratorTestCase), new BeforeTestExecutionCallback () {@Override public void beforeTestExecution (ExtensionContext extensionContext) {System.out.println (Systemxout.println; új AfterTestExecutionCallback () {@Override public void afterTestExecution (ExtensionContext extensionContext) {System.out.println ("AfterTestExecutionCallback: Disabled context");}}); }}; }

Először is, a featureDisabledContext módszerrel, a regisztrált kiterjesztések a következők:

  • GenericTypedParameterResolver - paraméterfeloldó kiterjesztés
  • BeforeTestExecutionCallback - egy életciklus-visszahívási kiterjesztés, amely közvetlenül a teszt végrehajtása előtt fut
  • AfterTestExecutionCallback - egy életciklusos visszahívási kiterjesztés, amely közvetlenül a teszt végrehajtása után fut

A második meghívási kontextusra azonban a featureEnabledContext módszerrel regisztráljunk egy másik kiterjesztéskészletet (a GenericTypedParameterResolver):

privát TestTemplateInvocationContext featureEnabledContext (UserIdGeneratorTestCase userIdGeneratorTestCase) {return new TestTemplateInvocationContext () {@Orride public String getDisplayName (int invocationIndex) {return userIdGeneratorTestCase.getDisplayName } @Orride public list getAdditionalExtensions () {return asList (new GenericTypedParameterResolver (userIdGeneratorTestCase), new DisabledOnQAEnvironmentExtension (), new BeforeEachCallback () {@Override public void beforeEach (ExtensionContext Extension. (ExtensionContext Extended.Contact.Enxt: EnxtPlaceCentertext.Contact.Enternate). );}}, új AfterEachCallback () {@Orride public void afterEach (ExtensionContext extensionContext) {System.out.println ("AfterEachCallback: Engedélyezett kontextus");}}); }}; }

A második meghívási környezetben az általunk regisztrált kiterjesztések a következők:

  • GenericTypedParameterResolver - paraméterfeloldó kiterjesztés
  • DisabledOnQAEnvironmentExtension - egy végrehajtási feltétel a teszt kikapcsolásához, ha a környezeti tulajdonság (a alkalmazás.tulajdonságok fájl)qa
  • BeforeEachCallback - egy életciklusos visszahívási kiterjesztés, amely az egyes tesztelési módszerek végrehajtása előtt fut
  • AfterEachCallback - egy életciklus-visszahívási kiterjesztés, amely az egyes vizsgálati módszerek végrehajtása után fut

A fenti példából egyértelműen látható, hogy:

  • ugyanazt a vizsgálati módszert több meghívási környezetben futtatják
  • minden meghívási környezet saját kiterjesztéskészletét használja, amelyek számukban és jellegükben egyaránt különböznek a többi meghívási kontextus kiterjesztéseitől

Ennek eredményeként egy vizsgálati módszer többször is meghívható, teljesen más meghívási környezetben, minden alkalommal. Több kontextus-szolgáltató regisztrálásával pedig még több olyan meghívási környezetet biztosíthatunk, amelyek alatt a teszt futtatható.

5. Következtetés

Ebben a cikkben megvizsgáltuk, hogy a JUnit 5 tesztsablonjai miként jelentik a paraméterezett és ismételt tesztek erőteljes általánosítását.

Először is megvizsgáltuk a paraméterezett tesztek néhány korlátját. Ezután megvitattuk, hogy a tesztsablonok miként lépik túl a korlátokat azáltal, hogy lehetővé teszik a teszt futtatását az egyes meghívásokhoz különböző kontextusban.

Végül megvizsgáltunk egy példát egy új tesztsablon létrehozására. Bontottuk a példát, hogy megértsük, hogyan működnek a sablonok az invokációs kontextus-szolgáltatókkal és az invokációs kontextusokkal együtt.

Mint mindig, a cikkben használt példák forráskódja elérhető a GitHubon.