Vérifier son code « à la main » avec des System.out.println fonctionne une fois, mais pas après chaque modification. Un test unitaire automatisé est un petit programme qui appelle votre code et vérifie le résultat. On peut en exécuter des centaines en quelques secondes, à chaque changement : c’est un filet de sécurité qui permet de modifier le code sans peur de tout casser.
JUnit 6 dans un projet Maven
JUnit est le framework de test standard en Java. La version actuelle, JUnit 6 (sortie en septembre 2025), exige Java 17 ou plus et garde l’API Jupiter (org.junit.jupiter) introduite avec JUnit 5 : le code de test s’écrit de la même façon, et ce cours s’applique aussi à un projet resté en JUnit 5. Nouveauté pratique : tous les modules JUnit (plateforme, Jupiter) portent désormais le même numéro de version.
Créez le squelette avec l’archétype Maven, puis le Maven Wrapper (mvnw), qui fixe la version de Maven du projet pour toute l’équipe :
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 \
-DgroupId=fr.boutique -DartifactId=boutique -DinteractiveMode=false
cd boutique
mvn wrapper:wrapper # crée mvnw, mvnw.cmd et .mvn/ ; ensuite on utilise ./mvnw
L’archétype génère un pom.xml ciblant Java 17 et JUnit 5.11 : passez-le à Java 25 et à JUnit 6. Le BOM junit-bom fixe en un seul endroit la version de tous les modules JUnit :
<properties>
<maven.compiler.release>25</maven.compiler.release>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>6.1.3</version> <!-- dernière version sur Maven Central lors de la rédaction -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <!-- API, moteur et tests paramétrés -->
<scope>test</scope>
</dependency>
</dependencies>
Dans un projet Spring Boot, ne déclarez pas de version : les starters de test de Spring Boot 4 apportent JUnit 6, Mockito et AssertJ.
Le code de production va dans src/main/java, les tests dans src/test/java, avec le même package.
Un premier test
// src/main/java/fr/boutique/Calculatrice.java
public class Calculatrice {
public int ajouter(int a, int b) { return a + b; }
}
// src/test/java/fr/boutique/CalculatriceTest.java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class CalculatriceTest {
@Test
void ajouter_deuxPositifs_renvoieLaSomme() {
// Arrange : préparer les données et l'objet testé
Calculatrice calc = new Calculatrice();
// Act : exécuter le comportement testé
int resultat = calc.ajouter(2, 3);
// Assert : vérifier le résultat
assertEquals(5, resultat);
}
}
@Testmarque une méthode de test. Depuis JUnit 5 (et toujours en JUnit 6), la classe et les méthodes peuvent rester package-private (sanspublic).assertEquals(attendu, obtenu): mettez toujours l’attendu en premier, sinon le message d’échec sera trompeur.- Le nom du test décrit le scénario :
methode_situation_resultatAttenduest une convention répandue.
Lancer les tests
./mvnw test # Maven via le wrapper (plugin Surefire) ; mvnw.cmd test sous Windows
./gradlew test # Gradle (avec useJUnitPlatform())
Les IDE (IntelliJ IDEA, VS Code, Eclipse) affichent un bouton d’exécution à côté de chaque test. En cas d’échec, JUnit affiche un message comme expected: <5> but was: <6> avec la ligne fautive.
Le cycle rouge / vert / refactor
Le TDD (Test-Driven Development) consiste à écrire le test avant le code :
- Rouge : écrire un test qui échoue (la fonctionnalité n’existe pas encore) ;
- Vert : écrire le code le plus simple qui le fait passer ;
- Refactor : améliorer le code, les tests garantissant que rien ne casse.
Même sans pratiquer le TDD strict, retenez qu’un bon test est rapide, isolé, répétable et vérifie un seul comportement.
Sur cette plateforme, JUnit n’est pas installé dans l’éditeur d’exercices : vous écrirez de petits tests « maison » dans
mainqui reproduisent exactement la logique de JUnit (comparer attendu et obtenu, afficher PASS ou FAIL). Les exemples JUnit de la leçon sont à exécuter dans votre projet Maven.
Exercices
Les solutions et les tests restent sur le serveur. Dans l'espace étudiant, ton code est exécuté et corrigé, et le tuteur donne des indices avant la solution.
Mon premier lanceur de tests
Reproduisez le principe d’
assertEquals. Écrivez une méthodestatic boolean verifierEgal(String nom, int attendu, int obtenu)qui affichePASS nomouFAIL nom: attendu X, obtenu Yet renvoie le résultat.Chaque ligne de l’entrée décrit un cas
a b attendu. Pour chaque cas, appelezCalculatrice.ajouter(a, b)et vérifiez le résultat avec le nomajouter(a, b). Terminez parRésultat : R/T tests réussis.import java.util.*; public class Main { static boolean verifierEgal(String nom, int attendu, int obtenu) { // TODO return false; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); Calculatrice calc = new Calculatrice(); int reussis = 0, total = 0; // TODO : lire les cas et les vérifier System.out.println("Résultat : " + reussis + "/" + total + " tests réussis"); } } class Calculatrice { int ajouter(int a, int b) { return a + b; } }Tester une fonction palindrome
Implémentez
static boolean estPalindrome(String s)qui ignore la casse et les espaces ("Esope reste ici et se repose"est un palindrome ; la chaîne vide aussi).Dans
main, écrivez quatre tests maison nommés exactementmotSimple("kayak"→ true),majuscules("Radar"→ true),phraseAvecEspaces(la phrase ci-dessus → true) etnonPalindrome("java"→ false), affichésPASS nomouFAIL nom. Ensuite, pour chaque ligne de l’entrée, affichezmot -> trueoumot -> false.import java.util.*; public class Main { static boolean estPalindrome(String s) { // TODO return false; } static void test(String nom, boolean attendu, boolean obtenu) { System.out.println((attendu == obtenu ? "PASS " : "FAIL ") + nom); } public static void main(String[] args) { // TODO : les quatre tests, puis l'exploration des lignes d'entrée } }Ordre des arguments
Dans
assertEquals(a, b)de JUnit, que doivent représenteraetb?- a = valeur obtenue, b = valeur attendue
- a = valeur attendue, b = valeur obtenue
- L'ordre n'a aucune importance
Quiz de fin de leçon
Quel import correspond à l’annotation @Test de JUnit 6 ?
- org.junit.Test
- org.junit.jupiter.api.Test
- java.test.Test
Dans quelle étape d’un test appelle-t-on la méthode testée ?
- Arrange
- Act
- Assert
Que signifie la phase « rouge » du TDD ?
- Écrire un test qui échoue avant d'écrire le code
- Supprimer les tests qui échouent
- Corriger un bug en production
La suite du cours
- Les assertions JUnit et le test des exceptions18 min
- Cycle de vie des tests et organisation16 min
- Tests paramétrés16 min
- Isoler le code : doubles de test et Mockito20 min