Integratietesten met Maven

1. Overzicht

Maven is de meest populaire build-tool in de Java-ruimte, terwijl integratietesten een essentieel onderdeel zijn van het ontwikkelingsproces. Daarom het is een logische keuze om integratietests met Maven te configureren en uit te voeren.

In deze tutorial bespreken we een aantal verschillende manieren om Maven te gebruiken voor integratietests en om integratietests te scheiden van unit-tests.

2. Voorbereiding

Om de demonstratiecode te laten lijken op een real-world project, zullen we een JAX-RS-applicatie opzetten. Deze applicatie wordt op een server geïmplementeerd voordat de integratietests worden uitgevoerd en daarna ontmanteld.

2.1. Maven-configuratie

We bouwen onze REST-applicatie rond Jersey - de referentie-implementatie van JAX-RS. Deze implementatie vereist een aantal afhankelijkheden:

 org.glassfish.jersey.containers jersey-container-servlet-core 2.27 org.glassfish.jersey.inject jersey-hk2 2.27 

We kunnen de laatste versies van deze afhankelijkheden hier en hier vinden.

We gebruiken de Jetty Maven-plug-in om een ​​testomgeving op te zetten. Deze plug-in start een Jetty-server tijdens de pre-integratie-test fase van de Maven-buildlevenscyclus en stopt deze vervolgens in de post-integratie-test fase.

Hier is hoe we de Jetty Maven-plug-in configureren pom.xml:

 org.eclipse.jetty steiger-maven-plugin 9.4.11.v20180605 8999 stop 9000 start-steiger pre-integratie-test start stop-steiger post-integratie-test stop 

Wanneer de Jetty-server opstart, luistert deze op poort 8999. De stopKey en stopPort configuratie-elementen worden uitsluitend gebruikt door de plug-in hou op doel en hun waarde is vanuit ons perspectief niet belangrijk.

Hier is waar u de nieuwste versie van de Jetty Maven-plug-in kunt vinden.

Een ander ding om op te merken is dat we de verpakking element in het pom.xml bestand naar oorlog, anders kan de Jetty-plug-in de server niet starten:

oorlog

2.2. Een REST-applicatie maken

Het eindpunt van de applicatie is heel eenvoudig - het retourneren van een welkomstbericht wanneer een GET-verzoek de contextroot bereikt:

@Path ("/") openbare klasse RestEndpoint {@GET openbare String hallo () {return "Welkom bij Baeldung!"; }}

Dit is hoe we de eindpuntklasse registreren bij Jersey:

pakket com.baeldung.maven.it; importeer org.glassfish.jersey.server.ResourceConfig; openbare klasse EndpointConfig breidt ResourceConfig {openbare EndpointConfig () {register (RestEndpoint.class) uit; }}

Om de Jetty-server op de hoogte te houden van onze REST-applicatie, kunnen we een klassieker gebruiken web.xml implementatie descriptor:

  rest-servlet org.glassfish.jersey.servlet.ServletContainer javax.ws.rs.Application com.baeldung.maven.it.EndpointConfig rest-servlet / * 

Deze descriptor moet in de directory worden geplaatst / src / main / webapp/ WEB-INF herkend te worden door de server.

2.3. Testcode aan de clientzijde

Alle testklassen in de volgende secties bevatten een enkele methode:

@Test openbare leegte whenSendingGet_thenMessageIsReturned () gooit IOException {String url = "// localhost: 8999"; URLConnection-verbinding = nieuwe URL (url) .openConnection (); probeer (InputStream response = connection.getInputStream (); Scannerscanner = nieuwe Scanner (antwoord)) {String responseBody = scanner.nextLine (); assertEquals ("Welkom bij Baeldung!", responseBody); }}

Zoals we kunnen zien, doet deze methode niets anders dan het verzenden van een GET-verzoek naar de webtoepassing die we eerder hebben ingesteld en het verifiëren van het antwoord.

3. Integratietesten in actie

Een belangrijk ding om op te merken over integratietesten is dat testmethoden duren vaak behoorlijk lang.

Daarom moeten we integratietests uitsluiten van de standaard build-levenscyclus, zodat ze het hele proces niet elke keer dat we een project bouwen, vertragen.

Een handige manier om integratietests te scheiden, is door build-profielen te gebruiken. Dit soort configuratie stelt ons in staat om integratietests alleen uit te voeren wanneer dat nodig is - door een geschikt profiel te specificeren.

In de volgende secties configureren we alle integratietests met build-profielen.

4. Testen met de Failsafe-plug-in

De eenvoudigste manier om integratietests uit te voeren, is door de Maven te gebruiken faalveilig inpluggen.

Standaard is de Maven trefzeker plugin voert unit tests uit tijdens de test fase, terwijl de faalveilig plug-in voert integratietests uit in het integratietest fase.

We kunnen testklassen met verschillende patronen benoemen voor die plug-ins om de bijgesloten tests afzonderlijk op te halen.

De standaard naamgevingsconventies die worden afgedwongen door trefzeker en faalveilig zijn verschillend, dus we hoeven alleen maar deze conventies te volgen om unit- en integratietests te scheiden.

De uitvoering van de trefzeker plug-in bevat alle klassen waarvan de naam begint met Test, of eindigt met Test, Tests of TestCase. In tegenstelling daarmee is de faalveilig plugin voert testmethoden uit in klassen waarvan de naam begint met HET, of eindigt met HET of ITCase.

Dit is waar we de documentatie over testopname voor kunnen vinden trefzeker, en hier is die voor faalveilig.

Laten we de faalveilig plug-in voor de POM met standaardconfiguratie:

 failsafe maven-failsafe-plugin 2.22.0 integratietest verifiëren 

Deze link is waar u de nieuwste versie van het faalveilig inpluggen.

Met de bovenstaande configuratie wordt de volgende testmethode uitgevoerd in het integratietest fase:

openbare klasse RestIT {// testmethode weergegeven in subsectie 2.3}

Omdat de Jetty-server opstart in het pre-integratie-test fase en wordt afgesloten in post-integratie-test, de test die we zojuist hebben gezien, slaagt met dit commando:

mvn verifiëren -Pfailsafe

We kunnen de naamgevingspatronen ook aanpassen om klassen met verschillende namen op te nemen:

 maven-failsafe-plugin 2.22.0 ** / * RestIT ** / RestITCase ... 

5. Testen met de Surefire-plug-in

Los van de faalveilig inpluggen, we kunnen ook de trefzeker plug-in om unit- en integratietests in verschillende fasen uit te voeren.

Laten we aannemen dat we alle integratietests een naam willen geven met het achtervoegsel Integratietest. Sinds de trefzeker plug-in voert tests uit met een dergelijke naam in de test fase standaard, moeten we ze uitsluiten van de standaarduitvoering:

 maven-surefire-plugin 2.22.0 ** / * IntegrationTest 

De nieuwste versie van deze plug-in is hier.

We hebben alle testklassen gevolgd met een naam die eindigt op Integratietest uit de build-levenscyclus. Het is tijd om ze terug te plaatsen met een profiel:

 surefire maven-surefire-plugin 2.22.0 integratietest test geen ** / * IntegrationTest 

In plaats van het test doel van de trefzeker plug-in naar de test build-fase, zoals gewoonlijk, hebben we deze gebonden aan de integratietest fase. De plug-in wordt dan geactiveerd tijdens het integratietestproces.

Merk op dat we een uitsluiten element naar geen om de uitsluiting die is gespecificeerd in de basisconfiguratie op te heffen.

Laten we nu een integratietestklasse definiëren met ons naamgevingspatroon:

openbare klasse RestIntegrationTest {// testmethode weergegeven in subsectie 2.3}

Deze test wordt uitgevoerd met het commando:

mvn verifiëren -Psurefire

6. Testen met de Cargo-plug-in

We kunnen de trefzeker plug-in met de Maven lading inpluggen. Deze plug-in wordt geleverd met ingebouwde ondersteuning voor embedded servers, die erg handig zijn voor integratietests.

Meer details over deze combinatie vind je hier.

7. Testen met JUnit's @Categorie

Een handige manier om selectief tests uit te voeren, is door gebruik te maken van de @Categorie annotatie in het JUnit 4-raamwerk. Met deze annotatie kunnen we bepaalde tests uitsluiten van unit-tests en deze opnemen in integratietests.

Ten eerste hebben we een interface of klasse nodig om als categorie-ID te werken:

pakket com.baeldung.maven.it; openbare interface-integratie {}

We kunnen dan een testklas versieren met de @Categorie annotatie en Integratie identificatie:

@Category (Integration.class) openbare klasse RestJUnitTest {// testmethode weergegeven in subsectie 2.3}

In plaats van het @Categorie annotatie op een testklasse, kunnen we deze ook op methodeniveau gebruiken om individuele testmethodes te categoriseren.

Een categorie uitsluiten van de test bouwfase is eenvoudig:

 maven-surefire-plugin 2.22.0 com.baeldung.maven.it.Integration 

Inclusief de Integratie categorie in de integratietest fase is ook eenvoudig:

 categorie maven-failsafe-plugin 2.22.0 ** / * com.baeldung.maven.it Integratie integratie-test verifiëren 

We kunnen nu integratietests uitvoeren met een Maven-opdracht:

mvn verifiëren -Pcategory

8. Een aparte directory toevoegen voor integratietests

Het is soms wenselijk om een ​​aparte directory te hebben voor integratietests. Door tests op deze manier te organiseren, kunnen we integratietests volledig isoleren van unit-tests.

We kunnen de Maven gebruiken helper bouwen plug-in voor dit doel:

 org.codehaus.mojo build-helper-maven-plugin 3.0.0 add-integratie-test-source genereren-test-bronnen add-test-source src / integratietest / java 

Hier kunnen we de nieuwste versie van deze plug-in vinden.

De configuratie die we zojuist hebben gezien, voegt een testbrondirectory toe aan de build. Laten we een klassendefinitie aan die nieuwe map toevoegen:

openbare klasse RestITCase {// testmethode weergegeven in paragraaf 2.3}

Het is tijd om integratietests uit te voeren in deze klasse:

mvn verifiëren -Pfailsafe

De Maven faalveilig plug-in zal methoden uitvoeren in deze testklasse vanwege de configuratie die we hebben ingesteld in subsectie 3.1.

Een testbrondirectory gaat vaak samen met een resourcemap. We kunnen zo'n directory aan een andere toevoegen executie element naar de plugin-configuratie:

 ... add-integratie-test-resource genereren-test-resources add-test-resource src / integratietest / resources 

9. Conclusie

Dit artikel ging verder met het gebruik van Maven om integratietests uit te voeren met een Jetty-server, met de nadruk op de configuratie van de Maven trefzeker en faalveilig plug-ins.

De volledige broncode voor deze tutorial is te vinden op GitHub.