Testen mit Testcontainers

Heute möchte ich euch eines meiner Lieblingstools vorstellen. Dieses Tool gehört bereits seit Jahren zu den festen Bestandteilen eines jeden Projekts, an dem ich arbeite. Bei diesem Tool handelt es sich um Testcontainers (https://testcontainers.com/). Mit Testcontainers lassen sich unter anderem verschiedene Datenbanken für Integration Tests hochfahren und dann gegen eine echte Datenbank laufen.

Konfiguration

Testcontainers liefert fertige Pakete für verschiedene Programmiersprachen aus, ich werde mich hier nur auf Java konzentrieren. Um die nötigen Pakete in einem Gradle Projekt mit Juni 5 zur Verfügung zu stellen, reichen folgende Zeilen aus:

Gradle

testImplementation "org.junit.jupiter:junit-jupiter:5.8.1" 
testImplementation "org.testcontainers:testcontainers:1.19.1" 
testImplementation "org.testcontainers:junit-jupiter:1.19.1" 
testImplementation "org.testcontainers:postgresql:1.19.1"

Analog in Maven:

Maven

<dependency> 
<groupId>org.junit.jupiter</groupId> 
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version> 
<scope>test</scope>. 
</dependency> 
<dependency> 
<groupId>org.testcontainers</groupId> 
<artifactId>testcontainers</artifactId> 
<version>1.19.1</version> 
<scope>test</scope> 
</dependency> 
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.19.1</version>
<scope>test</scope> 
</dependency> 
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.19.1</version> 
<scope>test</scope> 
</dependency>

Basis Klasse für Integration Tests

Hier ein Beispiel für eine Basisklasse für unsere Integration Tests:

Basisklasse in Java

@Testcontainers 
abstract class BasisIT { 
@Container 
private static final var POSTGRESQL_CONTAINER = new PostgreSQLContainer<> 
(DockerImageName.parse("postgres:9.6.12")); 
@BeforeAll 
static void configureDatabase() { 
System.setProperty("DB_URL", POSTGRESQL_CONTAINER.getJdbcUrl()); 
System.setProperty("DB_USERNAME", POSTGRESQL_CONTAINER.getUsername()); 
System.setProperty("DB_PASSWORD", POSTGRESQL_CONTAINER.getPassword()); 
} 
}

Eine passende application-test.properties sieht dann wie folgt aus und kann statisch hinterlegt

werden.

spring.datasource.url=${DB_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}

Die Annotations @Testcontainers und @Container sorgen dafür, dass die Docker-Container vor Testausführung gestartet und nach Testausführung wieder beendet werden. Man braucht hier keine Angst zu haben, dass Container nach Testende weiter existieren würden. Testcontainers sorgt nach Ausführung dafür, dass alle gestarteten Container wieder beendet werden.

Aus praktischen Gründen benutzen wir in unserem Setup nur 1 Datenbank-Instanz pro Testlauf, daher ist unser Container im Sourcecode static. Es ist auch möglich pro Test eine Datenbank Instanz zu starten oder verschiedene Datenbanken (zB. PostgreSQL und MySQL).

Teilen Sie diesen Beitrag

Das könnte dich auch interessieren …