Bevezetés a Testcontainers használatába Spring Boot alkalmazásban
Megjelent az első videóm, melynek témája, hogy hogyan lehet használni a Testcontainers-t Spring Boot alkalmazásban.
A videóhoz a forráskód is elérhető a GitHubon.
Ha valaki mégis a szöveges tartalomhoz ragaszkodik, olvasson tovább.
Integrációs tesztek, vagy fejlesztés közben az alkalmazás futtatásakor gyakran szükség van adatbázisra, vagy más háttérszolgáltatásra, mint pl. cachere vagy message brokerre. Használhatjuk a saját számítógépünkön lévőt, azonban ennek telepítése, frissítése körülményes lehet, különösen akkor, ha esetleg egyszerre két különböző verzióját szeretnénk használni. Relációs adatbázis esetén használhatunk pl. in-memory H2 adatbázist, ezzel azonban kompatibilitiási problémák merülhetnek fel. A virtualizáció, majd a konténerizáció ezen sokat segített.
A Testcontainers használatával a háttérszolgáltatásokat tartalmazó konténereket kódban tudjuk definiálni, és kezeli ezek életciklusát, azaz a megfelelő időben elindítja és leállítja őket.
A Spring Boot a 3.1-es verziótól kezdve különösképp támogatja a Testcontainers használatát. Nem egyedülálló módon, a Quarkusban is megjelenik Dev Services néven.
Az integrációs tesztek esetén a PostgreSQL konténer tehát Testcontainers segítségével indítható.
Ehhez először fel kell venni a spring-boot-testcontainers
és
postgresql
függőséget a pom.xml
fájlban.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
Valamint azért, hogy a konfiguráció és az elindított konténerek is újrafelhasználhatóak legyenek
a tesztesetek között, a Testcontainers konfigurációját érdemes kiszervezni egy TestcontainersConfiguration
osztályba. El kell látni a @TestConfiguration
annotációval, valamint létrehozni egy PostgreSQLContainer
típusú beant. Konstruktor paraméterben az image nevét várja, a reprodukálhatóság miatt érdemes pontos verziószámot használni.
Itt egyéb műveleteket is el lehet végezni, pl. környezeti váltózót beállítani, parancsot futtatni, vagy fájlt másolni.
@TestConfiguration(proxyBeanMethods = false)
public class TestcontainersConfiguration {
@Bean
@ServiceConnection
PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16.3");
}
}
El kell látni a @ServiceConnection
annotációval. Ekkor ugyanis létrejön egy ConnectionDetails
,
itt egy JdbcConnectionDetails
példány, mely tartalmazza a kapcsolódási paramétereket, mint
pl. a konténer portja, mivel ezt a Testcontainers random határozza meg. Ez felülírja
az application.properties
fájlban lévő értékeket.
Az osztályt az integrációs tesztben az @Import
annotációval lehet behivatkozni.
@Import(TestcontainersConfiguration.class)
A teszt futtatásakor a logban látható, hogy elindít egy konténert, és a Service fülön is látszik egy Postgres és egy másik konténer. (Ez utóbbi szabadítja fel a teszt futtatása után az erőforrásokat.) A teszt után eltűnnek a konténerek.
Két teszteset fut le, és mindkettő ugyanazt a konténert használja. Ugyanezt a konfigurációt importáló másik teszt osztályokban lévő tesztesetek is ugyanezt a konténert használnák.
A Spring Initializr is hasonló kódot generál, ha felvesszük a függőségek közé a Testconatiners-t.
De itt van még egy test application is. Ugyanis a teszt ágra is felvehető egy main
metódussal rendelkező osztály, mely szintén megkapja a
Testcontainers konfigurációt, így ha elindítjuk, vele elindul az adatbázis is.
public class TestEmployeesApplication {
public static void main(String[] args) {
SpringApplication.from(EmployeesApplication::main).with(TestcontainersConfiguration.class).run(args);
}
}
A Services fülön látható a futó konténer, valamint a http fájlból kéréseket indíthatunk az alkalmazás
felé (POST
, GET
).
Ha leállítjuk az alkalmazást, eltűnik a konténer.
Ezt használva, az alkalmazás Git clone után elindítható egy olyan gépen is, ahol csak egy JDK és egy Docker van telepítve.
mvnw spring-boot:test-run
Hiszen a Maven Wrapper letölti a Mavent, ha szükséges, a Testcontainers pedig elindítja a szükséges konténereket.