Docker-testcontainere i Java-tests

1. Introduktion

I denne vejledning ser vi på Java Testcontainere bibliotek. Det giver os mulighed for at bruge Docker-containere inden for vores test. Som et resultat kan vi skrive selvstændige integrationstest, der afhænger af eksterne ressourcer.

Vi kan bruge enhver ressource i vores tests, der har et dockerbillede. For eksempel er der billeder til databaser, webbrowsere, webservere og meddelelseskøer. Derfor kan vi køre dem som containere i vores test.

2. Krav

Testcontainere bibliotek kan bruges med Java 8 og nyere. Desuden er den kompatibel med JUnit Rules API.

Lad os først definere maven-afhængighed for kernefunktionaliteten:

 org.testcontainere testcontainere 1.11.4 

Der er også moduler til specialiserede containere. I denne vejledning bruger vi PostgreSQL og Selen.

Lad os tilføje de relevante afhængigheder:

 org.testcontainers postgresql 1.11.4 org.testcontainers selen 1.11.4 

Vi kan finde de nyeste versioner på Maven Central.

Vi har også brug for Docker til at køre containere. Se Docker-dokumentation for installationsinstruktioner.

Sørg for, at du er i stand til at køre Docker-containere i dit testmiljø.

3. Anvendelse

Lad os konfigurere en generisk containerregel:

@ClassRule offentlig statisk GenericContainer simpleWebServer = ny GenericContainer ("alpine: 3.2") .withExposedPorts (80) .withCommand ("/ bin / sh", "-c", "mens sand; gør ekko" + "\" HTTP / 1.1 200 OK \ n \ nHej verden! \ "| Nc -l -p 80; færdig");

Vi konstruerer en GenericContainer testregel ved at angive et docker-billednavn. Derefter konfigurerer vi det med buildermetoder:

  • Vi bruger medExposedPorts at udsætte en port fra containeren
  • med kommando definerer en containerkommando. Det udføres, når containeren starter.

Reglen er kommenteret med @ClassRule. Som et resultat vil den starte Docker-containeren, før nogen test i denne klasse kører. Containeren ødelægges, efter at alle metoder er udført.

Hvis du ansøger @Herske kommentar, GenericContainer regel starter en ny container for hver testmetode. Og det stopper beholderen, når testmetoden er færdig.

Vi kan bruge IP-adresse og port til at kommunikere med processen, der kører i containeren:

@Test offentlig ugyldighed givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse () kaster undtagelse {String address = "//" + simpleWebServer.getContainerIpAddress () + ":" + simpleWebServer.getMappedPort (80); Strengrespons = simpleGetRequest (adresse); assertEquals (svar, "Hello World!"); }

4. Brugsmetoder

Der er flere brugstilstande af testbeholderne. Vi så et eksempel på at køre en GenericContainer.

Testcontainere biblioteket har også regeldefinitioner med specialfunktionalitet. De er til containere med almindelige databaser som MySQL, PostgreSQL; og andre som webklienter.

Selvom vi kan køre dem som generiske containere, giver specialiseringerne udvidede bekvemmelighedsmetoder.

4.1. Databaser

Lad os antage, at vi har brug for en databaseserver til integrationstest til dataadgang-lag. Vi kan køre databaser i containere ved hjælp af TestContainers-biblioteket.

For eksempel affyrer vi en PostgreSQL-container med PostgreSQLContainer Herske. Derefter er vi i stand til at bruge hjælpemetoder. Disse er getJdbcUrl, getUsername, getPassword til databaseforbindelse:

@ Regel offentlig PostgreSQLContainer postgresContainer = ny PostgreSQLContainer (); @Test offentlig ugyldig nårSelectQueryExecuted_thenResulstsReturned () kaster Undtagelse {String jdbcUrl = postgresContainer.getJdbcUrl (); Streng brugernavn = postgresContainer.getUsername (); Strengadgangskode = postgresContainer.getPassword (); Forbindelse tilslut = DriverManager .getConnection (jdbcUrl, brugernavn, adgangskode); ResultSet resultSet = conn.createStatement (). ExecuteQuery ("SELECT 1"); resultSet.next (); int-resultat = resultSet.getInt (1); assertEquals (1, resultat); }

Det er også muligt at køre PostgreSQL som en generisk container. Men det ville være sværere at konfigurere forbindelsen.

4.2. Webdrivere

Et andet nyttigt scenario er at køre containere med webbrowsere. BrowserWebDriverContainer regel muliggør kørsel Chrome og Firefox i docker-selen containere. Derefter administrerer vi dem med RemoteWebDriver.

Dette er meget nyttigt til automatisering af UI / accepttest til webapplikationer:

@Rule public BrowserWebDriverContainer chrome = ny BrowserWebDriverContainer () .withCapabilities (nye ChromeOptions ()); @Test offentlig ugyldig nårNavigatedToPage_thenHeadingIsInThePage () {RemoteWebDriver driver = chrome.getWebDriver (); driver.get ("// eksempel.com"); Strengoverskrift = driver.findElement (By.xpath ("/ html / body / div / h1")) .getText (); assertEquals ("Eksempel Domæne", overskrift); }

4.3. Docker komponere

Hvis testene kræver mere komplekse tjenester, kan vi specificere dem i en docker-komponere fil:

simpleWebServer: image: alpine: 3.2 kommando: ["/ bin / sh", "-c", "mens den er sand; gentag 'HTTP / 1.1 200 OK \ n \ nHello World!' | nc -l -p 80; færdig "]

Så bruger vi DockerComposeContainer Herske. Denne regel starter og kører tjenester som defineret i komponentfilen.

Vi bruger getServiceHost og getServicePost metoder til at oprette forbindelsesadresse til tjenesten:

@ClassRule offentlig statisk DockerComposeContainer compose = ny DockerComposeContainer (ny fil ("src / test / resources / test-compose.yml")) .withExposedService ("simpleWebServer_1", 80); @Test offentlig ugyldighed givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse () kaster undtagelse {String address = "//" + compose.getServiceHost ("simpleWebServer_1", 80) + ":" + compose.getServicePort ("simpleWebServer_1", 80); Strengrespons = simpleGetRequest (adresse); assertEquals (svar, "Hello World"); }

5. Konklusion

Vi så, hvordan vi kunne bruge Testcontainere bibliotek. Det letter udvikling og kørsel af integrationstest.

Vi brugte GenericContainer regel for containere med givne dockerbilleder. Så kiggede vi på PostgreSQLContainer, BrowserWebDriverContainer og DockerComposeContainer regler. De giver mere funktionalitet til specifikke brugssager.

Endelig kan kodeeksempler her findes på GitHub.


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