Pisanje predložaka za test slučajeve pomoću JUnit-a 5

1. Pregled

Biblioteka JUnit 5 nudi brojne nove značajke u odnosu na svoje prethodne verzije. Jedna od takvih značajki su testni predlošci. Ukratko, predlošci za testiranje snažna su generalizacija parametriziranih i ponovljenih testova JUnit 5.

U ovom uputstvu naučit ćemo kako stvoriti testni predložak pomoću JUnit 5.

2. Ovisnosti Mavena

Počnimo s dodavanjem ovisnosti na našu pom.xml.

Moramo dodati glavni JUnit 5 junit-jupiter-motor ovisnost:

 org.junit.jupiter junit-jupiter-motor 5.7.0 

Uz ovo, trebat ćemo dodati i junit-jupiter-api ovisnost:

 org.junit.jupiter junit-jupiter-api 5.7.0 

Isto tako, u našu možemo dodati potrebne ovisnosti graditi.gradle datoteka:

testCompile grupa: 'org.junit.jupiter', naziv: 'junit-jupiter-engine', verzija: '5.7.0' testCompile grupa: 'org.junit.jupiter', naziv: 'junit-jupiter-api', verzija : "5.7.0"

3. Izjava o problemu

Prije nego što pogledamo predloške testa, pogledajmo ukratko parametrizirane testove JUnit 5. Parametarska ispitivanja omogućuju ubrizgavanje različitih parametara u metodu ispitivanja. Kao rezultat, kada pomoću parametarskih testova,možemo izvršiti jednu metodu ispitivanja više puta s različitim parametrima.

Pretpostavimo da bismo sada htjeli pokrenuti našu test metodu više puta - ne samo s različitim parametrima, već i svaki put pod različitim kontekstom pozivanja.

Drugim riječima, željeli bismo da se metoda ispitivanja izvršava više puta, sa svakim pozivom koristeći drugu kombinaciju konfiguracija kao što su:

  • koristeći različite parametre
  • priprema različitosti testne klase na drugačiji način - to jest ubrizgavanje različitih ovisnosti u testnu instancu
  • izvođenje testa pod različitim uvjetima, poput omogućavanja / onemogućavanja podskupina poziva, ako je okruženje "QA
  • trčanje s drugačijim ponašanjem povratnog poziva u životnom ciklusu - možda želimo postaviti i srušiti bazu podataka prije i nakon podskupina poziva

Korištenje parametarskih testova u ovom se slučaju pokazalo ograničenim. Srećom, JUnit 5 nudi moćno rješenje za ovaj scenarij u obliku testnih predloga.

4. Predlošci za testiranje

Predlošci za testove nisu test slučajevi. Umjesto toga, kao što im samo ime govori, oni su samo predlošci za zadate test slučajeve. Oni su snažna generalizacija parametriziranih i ponovljenih testova.

Predlošci za testiranje pozivaju se jednom za svaki kontekst poziva, koji im pruža pružatelj (i) konteksta poziva.

Pogledajmo sada primjer predložaka za testiranje. Kao što smo gore utvrdili, glavni akteri su:

  • metoda ispitivanja cilja
  • metoda testnog predloška
  • jedan ili više davatelja konteksta pozivanja registriranih metodom predloška
  • jedan ili više konteksta pozivanja koje pruža svaki pružatelj konteksta poziva

4.1. Metoda ispitivanja cilja

Za ovaj primjer koristit ćemo jednostavan UserIdGeneratorImpl.generate metoda kao naš testni cilj.

Definirajmo UserIdGeneratorImpl razred:

javna klasa UserIdGeneratorImpl implementira UserIdGenerator {private boolean isFeatureEnabled; javni UserIdGeneratorImpl (boolean isFeatureEnabled) {this.isFeatureEnabled = isFeatureEnabled; } javni String generiranje (String firstName, String lastName) {String InitialAndLastName = firstName.substring (0, 1) .concat (lastName); return isFeatureEnabled? "bael" .concat (početnoAndLastName): početnoAndLastName; }}

The generirati metoda, koja je naš cilj ispitivanja, uzima ime i prezime kao parametre i generira korisnički ID. Format korisničkog ID-a razlikuje se, ovisno o tome je li prekidač značajke omogućen ili ne.

Pogledajmo kako ovo izgleda:

Prekidač s obzirom na značajku onemogućen je Kada je firstName = "John" i lastName = "Smith" Tada se vraća "JSmith" S obzirom na to da je prekidač s obzirom na značajku omogućen Kada firstName = "John" i lastName = "Smith" Zatim se vrati "baelJSmith"

Dalje, napišimo metodu testnog predloška.

4.2. Metoda ispitnog predloška

Ovdje je predložak testa za našu metodu cilja testiranja UserIdGeneratorImpl.generate:

javna klasa UserIdGeneratorImplUnitTest {@TestTemplate @ExtendWith (UserIdGeneratorTestInvocationContextProvider.class) javna praznina whenUserIdRequiredThenUserIdIsReturnedInCorrectFormat (UserIdGeneratorTestCase testCase) { String actualUserId = userIdGenerator.generate (testCase.getFirstName (), testCase.getLastName ()); assertThat (actualUserId) .isEqualTo (testCase.getExpectedUserId ()); }}

Pogledajmo pobliže metodu testnog predloška.

Početi sa, izrađujemo metodu testnog predloška označavanjem JUnit 5 @TestTemplate bilješka.

Nakon toga, registriramo pružatelja konteksta, UserIdGeneratorTestInvocationContextProvider,koristiti @ExtendWith bilješka. Probnim predloškom možemo registrirati više pružatelja konteksta. Međutim, u svrhu ovog primjera, registriramo jednog pružatelja usluga.

Također, metoda predloška prima primjerak UserIdGeneratorTestCase kao parametar. Ovo je jednostavno klasa omota za ulaze i očekivani rezultat test slučaja:

javna klasa UserIdGeneratorTestCase {private boolean isFeatureEnabled; private String firstName; private String lastName; private String očekujeUserId; // Standardni postavljači i getteri}

Napokon, pozivamo se na metodu ispitivanja i tvrdimo da je taj rezultat očekivan

Sada je vrijeme da definiramo našeg davatelja konteksta pozivanja.

4.3. Pružatelj konteksta poziva

Moramo registrirati barem jednog TestTemplateInvocationContextProvider s našim testnim predloškom. Svaka registrirana TestTemplateInvocationContextProvider pruža a Stream od TestTemplateInvocationContext instance.

Prije toga, koristeći @ExtendWith bilješku, registrirali smo se UserIdGeneratorTestInvocationContextProvider kao naš davatelj poziva.

Definirajmo sada ovu klasu:

javna klasa UserIdGeneratorTestInvocationContextProvider implementira TestTemplateInvocationContextProvider {// ...}

Naš kontekst pozivanja implementira TestTemplateInvocationContextProvider sučelje, koje ima dvije metode:

  • supportsTestTemplate
  • provideTestTemplateInvocationContexts

Počnimo s primjenom supportsTestTemplate metoda:

@Override javna logička podrškaTestTemplate (ExtensionContext extensionContext) {return true; }

Izvršni mehanizam JUnit 5 poziva supportsTestTemplate metodu najprije za provjeru je li davatelj usluga primjenjiv za danu ExecutionContext. U ovom se slučaju jednostavno vraćamo pravi.

Sada, provedimo provideTestTemplateInvocationContexts metoda:

@Override public Stream provideTestTemplateInvocationContexts (ExtensionContext extensionContext) {boolean featureDisabled = false; logička značajkaEnabled = true; vratiti Stream.of (featureDisabledContext (new UserIdGeneratorTestCase ("Dati prekidač značajke onemogućen Kada je korisničko ime John Smith Tada je generirani userid JSmith", featureDisabled, "John", "Smith", "JSmith")), featureEnabledContext (novi UserIdGeneratorTestCase (" Dati je prekidač značajke omogućen Kada je korisničko ime John Smith Tada je generirani userid baelJSmith ", featureEnabled," John "," Smith "," baelJSmith "))); }

Svrha provideTestTemplateInvocationContexts metoda je pružanje a Stream od TestTemplateInvocationContext instance. Za naš primjer, vraća dvije instance, predviđene metodama featureDisabledContext i featureEnabledContext. Slijedom toga, naš će se predložak za testiranje pokrenuti dva puta.

Dalje, pogledajmo to dvoje TestTemplateInvocationContext instance vraćene ovim metodama.

4.4. Primjerci konteksta pozivanja

Konteksti pozivanja su implementacije TestTemplateInvocationContext sučelje i implementirati sljedeće metode:

  • getDisplayName - pružite testno ime za prikaz
  • getAdditionalExtensions - vratiti dodatna proširenja za kontekst poziva

Definirajmo featureDisabledContext metoda koja vraća našu prvu instancu konteksta poziva:

private TestTemplateInvocationContext featureDisabledContext (UserIdGeneratorTestCase userIdGeneratorTestCase) {return new TestTemplateInvocationContext () {@Override public String getDisplayName (int invocationIndex) {return userIdGeneratorTestCase.getDis; } @Override javni popis getAdditionalExtensions () {return asList (new GenericTypedParameterResolver (userIdGeneratorTestCase), new BeforeTestExecutionCallback () {@Override public void beforeTestExecution (ExtensionContext extensionContext) {System.outBext. novi AfterTestExecutionCallback () {@Override javna praznina afterTestExecution (ExtensionContext extensionContext) {System.out.println ("AfterTestExecutionCallback: Disabled context");}}); }}; }

Prvo, za kontekst pozivanja koji je vratio featureDisabledContext metode, proširenja koja registriramo su:

  • GenericTypedParameterResolver - proširenje razrješivača parametara
  • BeforeTestExecutionCallback - produženje povratnog poziva životnog ciklusa koje se izvodi neposredno prije izvođenja testa
  • AfterTestExecutionCallback - produženje povratnog poziva životnog ciklusa koje se izvodi odmah nakon izvođenja testa

Međutim, za drugi kontekst poziva, koji je vratio featureEnabledContext metodu, registrirajmo drugačiji skup proširenja (zadržavajući GenericTypedParameterResolver):

private TestTemplateInvocationContext featureEnabledContext (UserIdGeneratorTestCase userIdGeneratorTestCase) {return new TestTemplateInvocationContext () {@ Override public String getDisplayName (int invocationIndex) {return userIdGeneratorTestCase.getDis; } @Override javni popis getAdditionalExtensions () {return asList (new GenericTypedParameterResolver (userIdGeneratorTestCase), new DisabledOnQAEnvironmentExtension (), new BeforeEachCallback () {@Override public void beforeEach (ExtensionConteprl Ext. );}}, novi AfterEachCallback () {@Override javna praznina afterEach (ExtensionContext extensionContext) {System.out.println ("AfterEachCallback: Omogućeni kontekst");}}); }}; }

Za drugi kontekst pozivanja, proširenja koja registriramo su:

  • GenericTypedParameterResolver - proširenje razrješivača parametara
  • DisabledOnQAEnvironmentExtention - uvjet izvršenja za onemogućavanje testa ako je svojstvo okoline (učitano iz primjena.svojstva datoteka) je “qa
  • BeforeEachCallback - proširenje povratnog poziva životnog ciklusa koje se izvodi prije svakog izvršavanja metode ispitivanja
  • AfterEachCallback - produženje povratnog poziva životnog ciklusa koje se izvodi nakon svakog izvršavanja metode ispitivanja

Iz gornjeg primjera jasno je vidjeti da:

  • ista metoda ispitivanja izvodi se u više konteksta pozivanja
  • svaki kontekst pozivanja koristi vlastiti skup proširenja koja se razlikuju i brojem i prirodom od proširenja u drugim kontekstima pozivanja

Kao rezultat, metoda ispitivanja može se pozivati ​​više puta pod potpuno različitim kontekstom pozivanja svaki put. A registracijom više pružatelja konteksta, možemo pružiti još više dodatnih slojeva konteksta pozivanja pod kojima ćemo pokrenuti test.

5. Zaključak

U ovom smo članku pogledali kako su predlošci za testove JUnit 5 snažna generalizacija parametriziranih i ponovljenih testova.

Za početak smo pogledali neka ograničenja parametriziranih testova. Zatim smo razgovarali o tome kako predlošci testa prevladavaju ograničenja dopuštajući pokretanje testa pod različitim kontekstom za svaki poziv.

Na kraju smo pogledali primjer izrade novog testnog predloška. Razlomili smo primjer da bismo razumjeli kako predlošci rade zajedno s pružateljima konteksta pozivanja i kontekstima pozivanja.

Kao i uvijek, izvorni kod za primjere korištene u ovom članku dostupan je na GitHubu.


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