Tag: testcontainers, docker, testing, java, integration
Livello: intermedio
TL;DR: Libreria per eseguire container Docker usa-e-getta nei test di integrazione, garantendo un ambiente reale, isolato e replicabile.
Usa container Docker reali al posto di mock o database in-memory per i test.
Gestisce il ciclo di vita del container in automatico (avvio all'inizio, spegnimento alla fine).
Assegna porte casuali ai container per evitare conflitti con i servizi dell'host.
Offre moduli preconfigurati per database, message broker e altri servizi comuni.
Integra "wait strategies" per bloccare i test finché il servizio nel container non è pronto.
Richiede obbligatoriamente un demone Docker (o alternativa compatibile come Colima) attivo.
Pulisce le risorse tramite un container sidecar (Ryuk) che rimuove in background i container orfani.
Q: Perché Testcontainers è preferibile a un database in-memory come H2?R: Perché garantisce la massima fedeltà con la produzione, evitando errori subdoli dovuti a dialetti SQL o comportamenti specifici del vendor assenti in H2.
Q: Come si evita che i test diventino troppo lenti avviando container ogni volta?R: Uso il pattern Singleton, dichiarando il container statico e condividendo la stessa istanza per tutta la suite di test per abbattere l'overhead.
Hardcodare le porte di connessione ai servizi: bisogna sempre usare i metodi esposti dall'oggetto container per recuperare la porta dinamica.
Non impostare una Wait Strategy corretta per container custom, causando il fallimento dei test perché tentano di connettersi troppo presto.
Scarsa configurazione dell'ambiente di CI (es. pipeline isolate che non hanno accesso a un socket Docker valido).
@Testcontainers
class PostgresIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15-alpine")
.withDatabaseName("test_db")
.withUsername("test")
.withPassword("test");
@Test
void testDatabaseConnection() {
String jdbcUrl = postgres.getJdbcUrl();
String password = postgres.getPassword();
// Iniezione di queste credenziali dinamiche nel contesto dell'applicazione
}
}
[ ] Implementazione avanzata del Singleton Container pattern
[ ] Creazione e gestione di Network custom per far dialogare più container nei test
[ ] Utilizzo della funzionalità sperimentale "reuse" per velocizzare lo sviluppo locale
https://testcontainers.com/