Dans JUnit 5, l’annotation @ParameterizedTest
est utilisée pour exécuter une méthode de test plusieurs fois avec différents paramètres. Cela permet de réduire la duplication de code et d’améliorer la lisibilité des tests. Dans cet article, nous allons explorer l’utilité de @ParameterizedTest
en créant une classe Java avec une méthode prenant une chaîne de caractères en paramètre, puis en écrivant des tests pour cette classe en utilisant d’abord l’annotation @Test
, avant d’optimiser les tests en utilisant @ParameterizedTest
.
Classe Java avec méthode à tester
Voici une classe Java simple contenant une méthode prenant une chaîne de caractères en paramètre et retournant une valeur en fonction de la chaîne :
import java.util.Objects;
public class ShapeUtil {
public int getNumberOfSides(String shape) {
if (Objects.equals(shape, "carré")) {
return 4;
} else if (Objects.equals(shape, "triangle")) {
return 3;
} else {
return -1;
}
}
}
Tests avec @Test
Nous allons commencer par écrire des tests pour la classe ShapeUtil
en utilisant l’annotation @Test
:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ShapeUtilTest {
@Test
void testSquare() {
ShapeUtil shapeUtil = new ShapeUtil();
int sides = shapeUtil.getNumberOfSides("carré");
assertEquals(4, sides);
}
@Test
void testTriangle() {
ShapeUtil shapeUtil = new ShapeUtil();
int sides = shapeUtil.getNumberOfSides("triangle");
assertEquals(3, sides);
}
@Test
void testInvalidShape() {
ShapeUtil shapeUtil = new ShapeUtil();
int sides = shapeUtil.getNumberOfSides("cercle");
assertEquals(-1, sides);
}
}
Utilisation de @ParameterizedTest
Maintenant, nous allons optimiser ces tests en utilisant l’annotation @ParameterizedTest
. Cette annotation permet de fournir des sources de paramètres pour les tests, ce qui évite la duplication de code.
Types de sources pour @ParameterizedTest
Il existe plusieurs types de sources que l’on peut utiliser avec @ParameterizedTest
:
- @ValueSource : Fournit un tableau de valeurs simples en tant que paramètres.
- @EnumSource : Fournit une énumération en tant que source de paramètres.
- @MethodSource : Fournit une méthode qui retourne un flux de paramètres.
- @CsvSource : Fournit des paramètres à partir d’une liste de valeurs séparées par des virgules.
- @CsvFileSource : Fournit des paramètres à partir d’un fichier CSV.
Exemples d’utilisation des différentes sources
@ValueSource
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ShapeUtilParameterizedTest {
private ShapeUtil shapeUtil = new ShapeUtil();
@ParameterizedTest
@ValueSource(strings = {"carré", "triangle"})
void testGetNumberOfSides(String shape) {
int sides = shapeUtil.getNumberOfSides(shape);
assertEquals(shape.equals("carré") ? 4 : 3, sides);
}
}
Dans cet exemple, la méthode testGetNumberOfSides
est exécutée deux fois avec les paramètres “carré” et “triangle”.
@EnumSource
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ShapeUtilParameterizedTest {
private ShapeUtil shapeUtil = new ShapeUtil();
@ParameterizedTest
@EnumSource(Shape.class)
void testGetNumberOfSides(Shape shape) {
int sides = shapeUtil.getNumberOfSides(shape.name());
assertEquals(shape.getSides(), sides);
}
enum Shape {
carré(4), triangle(3);
private int sides;
Shape(int sides) {
this.sides = sides;
}
public int getSides() {
return sides;
}
}
}
Dans cet exemple, la méthode testGetNumberOfSides
est exécutée une fois pour chaque valeur de l’énumération Shape
.
@MethodSource
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
public class ShapeUtilParameterizedTest {
private ShapeUtil shapeUtil = new ShapeUtil();
@ParameterizedTest
@MethodSource("shapeProvider")
void testGetNumberOfSides(String shape, int expectedSides) {
int sides = shapeUtil.getNumberOfSides(shape);
assertEquals(expectedSides, sides);
}
private static Stream<Arguments> shapeProvider() {
return Stream.of(
Arguments.of("carré", 4),
Arguments.of("triangle", 3),
Arguments.of("cercle", -1)
);
}
}
Dans cet exemple, la méthode testGetNumberOfSides
est exécutée une fois pour chaque paire de paramètres fournie par la méthode shapeProvider
.
@CsvSource
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ShapeUtilParameterizedTest {
private ShapeUtil shapeUtil = new ShapeUtil();
@ParameterizedTest
@CsvSource({"carré, 4", "triangle, 3", "cercle, -1"})
void testGetNumberOfSides(String shape, int expectedSides) {
int sides = shapeUtil.getNumberOfSides(shape);
assertEquals(expectedSides, sides);
}
}
Dans cet exemple, la méthode testGetNumberOfSides
est exécutée une fois pour chaque paire de paramètres fournie par @CsvSource
.
@CsvFileSource
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ShapeUtilParameterizedTest {
private ShapeUtil shapeUtil = new ShapeUtil();
@ParameterizedTest
@CsvFileSource(resources = "/shapes.csv")
void testGetNumberOfSides(String shape, int expectedSides) {
int sides = shapeUtil.getNumberOfSides(shape);
assertEquals(expectedSides, sides);
}
}
Dans cet exemple, la méthode testGetNumberOfSides
est exécutée une fois pour chaque paire de paramètres lues à partir du fichier CSV “shapes.csv”.
Conclusion
Dans cet article, nous avons exploré l’utilisation de l’annotation @ParameterizedTest
dans JUnit 5 pour écrire des tests paramétrés. Nous avons vu comment optimiser les tests en utilisant différentes sources de paramètres, ce qui permet de réduire la duplication de code et d’améliorer la lisibilité des tests. En utilisant @ParameterizedTest
, les développeurs peuvent écrire des tests plus concis et maintenables, ce qui contribue à la qualité globale du code.
En utilisant les différentes sources de paramètres disponibles, les développeurs peuvent choisir la méthode qui convient le mieux à leur cas d’utilisation spécifique, ce qui rend les tests plus flexibles et adaptables aux besoins changeants du projet.
En conclusion, l’utilisation de @ParameterizedTest
dans JUnit 5 est un outil puissant pour écrire des tests paramétrés de manière efficace et élégante.