Tests d'intégration d'applications Java avec Docker
Le développement Java moderne est impensable sans des tests de qualité. Cependant, les tests unitaires ne parviennent souvent pas à détecter les problèmes qui surviennent lors de l'interaction des composants avec des bases de données réelles, des files d'attente de messages ou des API externes. C'est là que les tests d'intégration entrent en jeu, et Docker rend ce processus simple, reproductible et isolé. Dans cet article, nous allons voir comment utiliser efficacement Docker pour les tests d'intégration d'applications Java, en utilisant la bibliothèque Testcontainers et Docker Compose.
Pourquoi Docker change la donne dans les tests d'intégration ?
L'approche traditionnelle des tests d'intégration nécessite souvent l'installation et la configuration de toutes les dépendances (bases de données, courtiers de messages) sur la machine locale du développeur ou sur le serveur CI. Cela entraîne un certain nombre de problèmes :
- Instabilité de l'environnement : Différentes versions de SGBD, conflits de ports, différence entre l'environnement de développement et la production.
- Complexité de la configuration CI/CD : Nécessité d'installer et de configurer manuellement les services dans le pipeline.
- Pollution des données : Les données de test peuvent rester dans la base de données locale, affectant les exécutions suivantes.
- Parallélisation : L'exécution simultanée de tests sur une même machine peut entraîner des conflits.
Docker résout ces problèmes en fournissant des conteneurs légers, isolés et éphémères. Chaque test (ou ensemble de tests) peut lancer sa propre instance de PostgreSQL, Redis ou Kafka, et après la fin du test, la détruire. Cela garantit la propreté et la reproductibilité des résultats.
Configuration du projet : Testcontainers vs Docker Compose
Il existe deux approches principales pour intégrer Docker dans les tests Java. Examinons les deux.
1. Testcontainers : une bibliothèque pour gérer les conteneurs depuis le code
Testcontainers est une bibliothèque Java qui permet de gérer le cycle de vie des conteneurs Docker directement depuis vos tests. C'est la norme de facto pour les tests d'intégration dans l'écosystème Spring Boot et au-delà.
Avantages :
- Gestion programmatique : les conteneurs sont démarrés et arrêtés automatiquement.
- Prise en charge des services populaires "prêts à l'emploi" (GenericContainer, PostgreSQLContainer, KafkaContainer, etc.).
- Sélection automatique des ports libres (évite les conflits).
- Idéal pour les tests d'intégration unitaires.
Exemple : Test d'un contrôleur REST avec PostgreSQL
Ajoutez la dépendance à votre pom.xml (Maven) :
<dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers</artifactId> <version>1.19.3</version> <scope>test</scope></dependency><dependency> <groupId>org.testcontainers</groupId> <artifactId>postgresql</artifactId> <version>1.19.3</version> <scope>test</scope></dependency>Écrivons maintenant un test pour une application Spring Boot qui fonctionne avec PostgreSQL :
import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.boot.test.web.client.TestRestTemplate;import org.springframework.http.ResponseEntity;import org.testcontainers.containers.PostgreSQLContainer;import org.testcontainers.junit.jupiter.Container;import org.testcontainers.junit.jupiter.Testcontainers;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnviron