jeudi 30 mai 2024

How to use Testcontainers in SpringBoot?

Introduction

Les tests d'intégration jouent un rôle crucial dans le développement logiciel moderne. Cependant, les tests avec des mocks ou des services en mémoire peuvent ne pas représenter fidèlement les environnements de production, entraînant des bugs inattendus. C'est là que Testcontainers entre en jeu.

Pourquoi avons-nous besoin de Testcontainers ?

Les Défis des Tests Traditionnels

Les tests traditionnels avec des mocks ou des services en mémoire présentent plusieurs limitations, notamment :

  • Incapacité à simuler des environnements de production réels
  • Fonctionnalités sous-jacentes différentes
  • Difficulté à identifier les bugs en environnement de développement

Les Avantages de Testcontainers

Testcontainers permet d'exécuter des tests d'intégration avec des services réels en utilisant des conteneurs Docker, ce qui :

  • Offre un environnement de test plus proche de la production
  • Réduit les bugs en production
  • Améliore la fiabilité des tests

Prérequis pour Réaliser ce TP

Prérequis Techniques

  1. JDK : Utilisez le JDK 21.0.1 ou une version ultérieure. Téléchargez-le ici.
  2. Maven : Utilisez Maven 3.9.7, la dernière version stable. Téléchargez-le ici.
  3. Docker : Utilisez Docker Engine 24.0.9, la dernière version stable. Téléchargez-le ici.

Prérequis de Connaissances

  1. Java
  2. Spring Boot
  3. JUnit
  4. Docker

Installation des Dépendances

Ajoutez les dépendances suivantes à votre fichier pom.xml pour Testcontainers :

xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-testcontainers</artifactId> <version>1.19.8</version> <!-- Utilisez la dernière version de Testcontainers --> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>junit-jupiter</artifactId> <version>1.19.8</version> <!-- Assurez-vous que cette version correspond à celle de Testcontainers --> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>postgresql</artifactId> <version>1.19.8</version> <!-- Utilisez la version de PostgreSQL correspondante --> <scope>test</scope> </dependency>

Cas de Test

Dans l'exemple ci-dessous, nous essayons de tester une API Rest qui crée et récupère les détails des étudiants. La base de données utilisée pour stocker les données des étudiants est PostgreSQL. Avant de commencer, assurez-vous que Docker est en cours d'exécution.

java
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Testcontainers public class StudentControllerTest { @Autowired private TestRestTemplate restTemplate; @Autowired private StudentRepository studentRepository; @Container static PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:15-alpine"); @Test public void testAddNewStudent() { // Given Student student = new Student(); student.setName("Alice"); student.setDateOfBirth("02/02/2021"); student.setGrade("II"); // When ResponseEntity<Student> studentResponseEntity = restTemplate. postForEntity("/students", student, Student.class); // Then Student savedStudent = studentResponseEntity.getBody(); assertEquals(HttpStatus.OK, studentResponseEntity.getStatusCode()); assertNotNull(savedStudent); } @Test public void testFetchStudentById() { // Given Student student = new Student(); student.setName("Bob"); student.setDateOfBirth("03/03/2022"); student.setGrade("III"); studentRepository.save(student); // When ResponseEntity<Student> studentResponseEntity = restTemplate. getForEntity("/students/" + student.getId(), Student.class); // Then Student studentResponse = studentResponseEntity.getBody(); assertEquals(HttpStatus.OK, studentResponseEntity.getStatusCode()); assertNotNull(studentResponse); assertEquals(1, studentResponse.getId()); assertEquals(student.getName(), studentResponse.getName()); assertEquals(student.getDateOfBirth(), studentResponse.getDateOfBirth()); assertEquals(student.getGrade(), studentResponse.getGrade()); } }

Exécution des Tests

Avant d'exécuter les tests, assurez-vous que Docker est en cours d'exécution. Utilisez ensuite la commande suivante dans le répertoire racine de votre projet :

bash
./mvnw test

Annotations et Classes Importantes

  • SpringBootTest : Crée un ApplicationContext et exécute l'environnement web entier utilisé pour le test.
  • webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT : Un port disponible est choisi au hasard chaque fois que le test est exécuté.
  • Testcontainers et Containers : Utilisés pour gérer le cycle de vie de démarrage et d'arrêt des conteneurs.
  • TestRestTemplate : De Spring, utilisé pour appeler et tester les points de terminaison REST à travers les cas de test.
  • ServiceConnection : Introduit dans SpringBoot 3.1, utilisé pour enregistrer la connexion de la base de données dans le conteneur au lieu de la mentionner manuellement en utilisant l'annotation DynamicPropertySource.
  • PostgreSQLContainer<>("postgres:15-alpine") : Télécharge la version 15 de PostgreSQL basée sur Alpine Linux comme image de base lorsque le conteneur se lance.

Conclusion

En utilisant Testcontainers, vous pouvez améliorer la fiabilité de vos tests d'intégration en exécutant des services réels dans des conteneurs Docker, créant ainsi un environnement de test plus proche de la production. Cela permet de réduire les bugs qui peuvent survenir en production en s'assurant que vos tests sont exécutés dans un environnement similaire. Testcontainers offre une solution puissante pour tester les intégrations avec des services réels, éliminant les limitations des mocks ou des services en mémoire, et contribuant à une meilleure qualité globale du logiciel. Essayez Testcontainers dans vos projets pour découvrir ses avantages par vous-même.

@DataJpaTest and Repository Class in JUnit | Baeldung
Configuring Separate Spring DataSource for Tests | Baeldung

Aucun commentaire:

Enregistrer un commentaire

to criticize, to improve