En este tema, aprenderemos cómo utilizar la anotación @ParameterizedTest
en JUnit para ejecutar un mismo test con diferentes conjuntos de datos. Los tests parametrizados son útiles cuando queremos probar un método con múltiples entradas y verificar que produce las salidas esperadas para cada una de ellas.
¿Qué es @ParameterizedTest?
La anotación @ParameterizedTest
en JUnit permite ejecutar un test varias veces con diferentes argumentos. Esto es especialmente útil para evitar la duplicación de código y para asegurarse de que un método funcione correctamente con una variedad de datos de entrada.
Configuración Básica
Para utilizar @ParameterizedTest
, necesitamos agregar la dependencia de JUnit 5 en nuestro proyecto. Aquí está el archivo pom.xml
para un proyecto Maven:
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.7.0</version> <scope>test</scope> </dependency>
Ejemplo Básico de @ParameterizedTest
Vamos a crear un test parametrizado que verifique si un número es par. Primero, definimos el método que queremos probar:
Ahora, creamos un test parametrizado para este método:
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; public class NumberUtilsTest { @ParameterizedTest @ValueSource(ints = {2, 4, 6, 8, 10}) void testIsEven(int number) { assertTrue(NumberUtils.isEven(number)); } @ParameterizedTest @ValueSource(ints = {1, 3, 5, 7, 9}) void testIsNotEven(int number) { assertFalse(NumberUtils.isEven(number)); } }
Explicación del Código
- @ParameterizedTest: Indica que el método es un test parametrizado.
- @ValueSource: Proporciona una lista de valores que se pasarán como argumentos al método de test. En este caso, estamos pasando una lista de enteros.
Proveedores de Argumentos
JUnit 5 proporciona varios proveedores de argumentos que podemos usar con @ParameterizedTest
:
- @ValueSource: Proporciona una lista de valores literales.
- @EnumSource: Proporciona valores de un tipo enumerado.
- @CsvSource: Proporciona una lista de valores en formato CSV.
- @MethodSource: Proporciona valores desde un método estático.
Ejemplo con @CsvSource
Vamos a extender nuestro ejemplo para probar un método que suma dos números:
El test parametrizado usando @CsvSource
se vería así:
import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; public class MathUtilsTest { @ParameterizedTest @CsvSource({ "1, 1, 2", "2, 3, 5", "3, 5, 8", "4, 6, 10" }) void testAdd(int a, int b, int expected) { assertEquals(expected, MathUtils.add(a, b)); } }
Explicación del Código
- @CsvSource: Proporciona una lista de valores en formato CSV. Cada línea representa un conjunto de argumentos que se pasarán al método de test.
Ejercicio Práctico
Ejercicio
Crea un test parametrizado para un método que verifica si una cadena es un palíndromo. Un palíndromo es una palabra que se lee igual de adelante hacia atrás.
- Define el método
isPalindrome
en una claseStringUtils
. - Crea un test parametrizado usando
@ValueSource
para verificar diferentes cadenas.
Solución
public class StringUtils { public static boolean isPalindrome(String str) { String cleaned = str.replaceAll("\\s+", "").toLowerCase(); return new StringBuilder(cleaned).reverse().toString().equals(cleaned); } }
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; public class StringUtilsTest { @ParameterizedTest @ValueSource(strings = {"madam", "racecar", "radar", "level", "rotor"}) void testIsPalindrome(String str) { assertTrue(StringUtils.isPalindrome(str)); } @ParameterizedTest @ValueSource(strings = {"hello", "world", "java", "programming"}) void testIsNotPalindrome(String str) { assertFalse(StringUtils.isPalindrome(str)); } }
Conclusión
En esta sección, hemos aprendido cómo usar @ParameterizedTest
en JUnit para ejecutar tests con diferentes conjuntos de datos. Hemos visto ejemplos prácticos utilizando @ValueSource
y @CsvSource
, y hemos creado un ejercicio para reforzar los conceptos aprendidos. En el siguiente tema, exploraremos cómo crear tests parametrizados personalizados para casos más complejos.
Curso de JUnit
Módulo 1: Introducción a JUnit
Módulo 2: Anotaciones Básicas de JUnit
- Entendiendo @Test
- Usando @Before y @After
- Usando @BeforeClass y @AfterClass
- Ignorando Tests con @Ignore
Módulo 3: Aserciones en JUnit
Módulo 4: Tests Parametrizados
- Introducción a los Tests Parametrizados
- Creando Tests Parametrizados
- Usando @ParameterizedTest
- Tests Parametrizados Personalizados
Módulo 5: Suites de Tests
Módulo 6: Mocking con JUnit
Módulo 7: Características Avanzadas de JUnit
Módulo 8: Mejores Prácticas y Consejos
- Escribiendo Tests Efectivos
- Organizando el Código de Tests
- Desarrollo Guiado por Tests (TDD)
- Integración Continua con JUnit