Migreren van JUnit 4 naar JUnit 5

1. Overzicht

In dit artikel zullen we zien hoe we kunnen migreren van JUnit 4 naar de nieuwste JUnit 5-release - met een overzicht van de verschillen tussen de twee versies van de bibliotheek.

Zie ons artikel hier voor de algemene richtlijnen voor het gebruik van JUnit 5.

2. JUnit 5 voordelen

Laten we beginnen met de vorige versie - JUnit 4 heeft een aantal duidelijke beperkingen:

  • Het volledige framework was opgenomen in een enkele jar-bibliotheek. De hele bibliotheek moet worden geïmporteerd, zelfs als alleen een bepaalde functie vereist is. In JUnit 5 krijgen we meer granulariteit en kunnen we alleen importeren wat nodig is
  • Eén testrunner kan alleen tests uitvoeren in JUnit 4 tegelijk (bijv. SpringJUnit4ClassRunner of Geparametriseerd ). Met JUnit 5 kunnen meerdere hardlopers tegelijkertijd werken
  • JUnit 4 is nooit verder gekomen dan Java 7 en miste veel functies van Java 8. JUnit 5 maakt goed gebruik van Java 8-functies

Het idee achter JUnit 5 was om JUnit 4 volledig te herschrijven om de meeste van deze nadelen op te lossen.

3. Verschillen

JUnit 4 is onderverdeeld in modules die JUnit 5 omvatten:

  • JUnit-platform - deze module bestrijkt alle uitbreidingsframeworks waarin we mogelijk geïnteresseerd zijn in het uitvoeren, ontdekken en rapporteren van tests
  • JUnit Vintage - deze module maakt achterwaartse compatibiliteit met JUnit 4 of zelfs JUnit 3 mogelijk

3.1. Annotaties

JUnit 5 wordt geleverd met belangrijke wijzigingen in de annotaties. De belangrijkste is dat we niet meer kunnen gebruiken @Test annotatie voor het specificeren van verwachtingen.

De verwacht parameter in JUnit 4:

@Test (verwacht = Exception.class) public void shouldRaiseAnException () gooit uitzondering {// ...}

Nu kunnen we een methode gebruiken assertThrows:

public void shouldRaiseAnException () gooit uitzondering {Assertions.assertThrows (Exception.class, () -> {// ...}); }

De time-out attribuut in JUnit 4:

@Test (timeout = 1) public void shouldFailBecauseTimeout () gooit InterruptedException {Thread.sleep (10); }

Nu de assertTimeout methode in JUnit 5:

@Test openbare leegte shouldFailBecauseTimeout () gooit InterruptedException {Assertions.assertTimeout (Duration.ofMillis (1), () -> Thread.sleep (10)); }

Andere annotaties die zijn gewijzigd in JUnit 5:

  • @Voordat annotatie wordt hernoemd naar @BeforeEach
  • @Na annotatie wordt hernoemd naar @Na elke
  • @Voor klas annotatie wordt hernoemd naar @Voor alles
  • @Na de les annotatie wordt hernoemd naar @Ten slotte
  • @Negeren annotatie wordt hernoemd naar @Gehandicapt

3.2. Beweringen

We kunnen nu assertion messages schrijven in een lambda in JUnit 5, waardoor de luie evaluatie de complexe berichtconstructie overslaat totdat het nodig is:

@Test public void shouldFailBecauseTheNumbersAreNotEqual_lazyEvaluation () {Assertions.assertTrue (2 == 3, () -> "Numbers" + 2 + "en" + 3 + "zijn niet gelijk!"); }

We kunnen beweringen ook groeperen in JUnit 5:

@Test openbare leegte shouldAssertAllTheGroup () {Lijstlijst = Arrays.asList (1, 2, 4); Assertions.assertAll ("Lijst is niet incrementeel", () -> Assertions.assertEquals (list.get (0) .intValue (), 1), () -> Assertions.assertEquals (list.get (1) .intValue ( ), 2), () -> Assertions.assertEquals (list.get (2) .intValue (), 3)); }

3.3. Veronderstellingen

De nieuwe Veronderstellingen klas is nu binnen org.junit.jupiter.api. veronderstellingen. JUnit 5 ondersteunt de bestaande aannames-methoden in JUnit 4 volledig en voegt ook een reeks nieuwe methoden toe om sommige beweringen alleen in specifieke scenario's uit te voeren:

@Test openbare leegte whenEnvironmentIsWeb_thenUrlsShouldStartWithHttp () {aannameThat ("WEB" .equals (System.getenv ("ENV")), () -> {assertTrue ("http" .startsWith (adres));}); }

3.4. Taggen en filteren

In JUnit 4 konden we tests groeperen met behulp van de @Categorie annotatie. Met JUnit 5 kan de @Categorie annotatie wordt vervangen door de @Label annotatie:

@Tag ("annotations") @Tag ("junit5") @RunWith (JUnitPlatform.class) openbare klasse AnnotationTestExampleTest {/*...*/}

We kunnen bepaalde tags opnemen / uitsluiten met behulp van de maven-surefire-plugin:

   maven-surefire-plugin junit5 

3.5. Nieuwe annotaties voor lopende tests

De @Rennen met werd gebruikt om de testcontext te integreren met andere frameworks of om de algehele uitvoeringsstroom in de testcases in JUnit 4 te veranderen.

Met JUnit 5 kunnen we nu de @ExtendWith annotatie om vergelijkbare functionaliteit te bieden.

Om als voorbeeld de Spring-functies in JUnit 4 te gebruiken:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration ({"/app-config.xml", "/test-data-access-config.xml"}) openbare klasse SpringExtensionTest {/*...*/}

Nu, in JUnit 5 is het een eenvoudige extensie:

@ExtendWith (SpringExtension.class) @ContextConfiguration ({"/app-config.xml", "/test-data-access-config.xml"}) openbare klasse SpringExtensionTest {/*...*/} 

3.6. Annotaties van nieuwe testregels

In JUnit 4 is het @Regel en @ClassRule annotaties werden gebruikt om speciale functionaliteit aan tests toe te voegen.

In JUnit 5. kunnen we dezelfde logica reproduceren met de @ExtendWith annotatie.

Stel dat we bijvoorbeeld een aangepaste regel hebben in JUnit 4 om logboeksporen voor en na een test te schrijven:

public class TraceUnitTestRule implementeert TestRule {@Override public Statement apply (Statement base, Description description) {return new Statement () {@Override public void evalu () gooit Throwable {// Voor en na een evaluatie tracering hier ...}}; }}

En we implementeren het in een testsuite:

@Rule openbaar TraceUnitTestRule traceRuleTests = nieuwe TraceUnitTestRule (); 

In JUnit 5 kunnen we hetzelfde op een veel intuïtievere manier schrijven:

openbare klasse TraceUnitExtension implementeert AfterEachCallback, BeforeEachCallback {@Override public void beforeEach (TestExtensionContext-context) gooit Exception {// ...} @Override public void afterEach (TestExtensionContext-context) gooit Exception {// ...}}

Met behulp van JUnit 5's AfterEachCallback en BeforeEachCallback interfaces beschikbaar in het pakket org.junit.jupiter.api.extension, we implementeren deze regel eenvoudig in de testsuite:

@RunWith (JUnitPlatform.class) @ExtendWith (TraceUnitExtension.class) openbare klasse RuleExampleTest {@Test openbare leegte whenTracingTests () {/*...*/}}

3.7. JUnit 5 Vintage

JUnit Vintage helpt bij de migratie van JUnit-tests door JUnit 3- of JUnit 4-tests uit te voeren binnen de JUnit 5-context.

We kunnen het gebruiken door de JUnit Vintage Engine te importeren:

 org.junit.vintage junit-vintage-engine $ {junit5.vintage.version} test 

4. Conclusie

Zoals we in dit artikel hebben gezien, is JUnit 5 een modulaire en moderne versie van het JUnit 4-framework. We hebben de belangrijkste verschillen tussen deze twee versies geïntroduceerd en laten doorschemeren hoe u van de ene naar de andere kunt migreren.

De volledige implementatie van deze tutorial is te vinden op GitHub.