En este tema, aprenderemos cómo crear tests parametrizados personalizados en JUnit. Los tests parametrizados permiten ejecutar el mismo test varias veces con diferentes datos de entrada, lo que es útil para verificar que el código funcione correctamente con una variedad de casos.
Conceptos Clave
- Tests Parametrizados: Tests que se ejecutan múltiples veces con diferentes conjuntos de datos.
- @ParameterizedTest: Anotación que indica que un método de test es parametrizado.
- @ValueSource, @CsvSource, @MethodSource: Anotaciones que proporcionan diferentes formas de suministrar datos a los tests parametrizados.
Ejemplo Básico de Test Parametrizado
Antes de profundizar en los tests parametrizados personalizados, revisemos un ejemplo básico de un test parametrizado usando @ValueSource
.
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import static org.junit.jupiter.api.Assertions.assertTrue; public class BasicParameterizedTest { @ParameterizedTest @ValueSource(strings = {"racecar", "radar", "level"}) void testPalindrome(String candidate) { assertTrue(isPalindrome(candidate)); } boolean isPalindrome(String str) { return str.equals(new StringBuilder(str).reverse().toString()); } }
En este ejemplo, el método testPalindrome
se ejecuta tres veces, una vez para cada valor en @ValueSource
.
Creando Tests Parametrizados Personalizados
Para crear tests parametrizados personalizados, podemos usar @MethodSource
para proporcionar datos de entrada desde un método. Esto nos da la flexibilidad de generar datos de prueba de manera dinámica.
Paso 1: Definir el Método de Fuente de Datos
El método de fuente de datos debe devolver un Stream
de argumentos. Aquí hay un ejemplo de cómo definir un método de fuente de datos:
import java.util.stream.Stream; import org.junit.jupiter.params.provider.Arguments; import static org.junit.jupiter.params.provider.Arguments.arguments; public class CustomParameterizedTest { static Stream<Arguments> provideStringsForIsBlank() { return Stream.of( arguments(" ", true), arguments("", true), arguments("not blank", false) ); } }
Paso 2: Usar @MethodSource en el Test
Ahora, podemos usar @MethodSource
en nuestro test para consumir los datos proporcionados por el método provideStringsForIsBlank
.
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.assertEquals; public class CustomParameterizedTest { @ParameterizedTest @MethodSource("provideStringsForIsBlank") void testIsBlank(String input, boolean expected) { assertEquals(expected, isBlank(input)); } boolean isBlank(String str) { return str == null || str.trim().isEmpty(); } }
En este ejemplo, el método testIsBlank
se ejecuta tres veces con diferentes conjuntos de datos proporcionados por provideStringsForIsBlank
.
Ejercicio Práctico
Ejercicio
Crea un test parametrizado personalizado que verifique si una cadena es un anagrama de otra. Un anagrama es una palabra o frase que se forma reorganizando las letras de otra palabra o frase.
- Define un método de fuente de datos que proporcione pares de cadenas y un valor booleano indicando si son anagramas.
- Escribe un test parametrizado que use este método de fuente de datos.
Solución
import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Arrays; public class AnagramTest { static Stream<Arguments> provideStringsForAnagramTest() { return Stream.of( arguments("listen", "silent", true), arguments("triangle", "integral", true), arguments("apple", "pale", false) ); } @ParameterizedTest @MethodSource("provideStringsForAnagramTest") void testIsAnagram(String str1, String str2, boolean expected) { assertEquals(expected, isAnagram(str1, str2)); } boolean isAnagram(String str1, String str2) { char[] charArray1 = str1.toCharArray(); char[] charArray2 = str2.toCharArray(); Arrays.sort(charArray1); Arrays.sort(charArray2); return Arrays.equals(charArray1, charArray2); } }
Explicación
- Método de Fuente de Datos:
provideStringsForAnagramTest
proporciona pares de cadenas y un valor booleano indicando si son anagramas. - Test Parametrizado:
testIsAnagram
usa@MethodSource
para consumir los datos y verifica si las cadenas son anagramas usando el métodoisAnagram
.
Conclusión
En esta sección, hemos aprendido cómo crear tests parametrizados personalizados en JUnit usando @MethodSource
. Esta técnica nos permite generar datos de prueba de manera dinámica y ejecutar tests con diferentes conjuntos de datos, lo que mejora la cobertura y la robustez de nuestras pruebas.
En el próximo módulo, exploraremos cómo agrupar y ejecutar múltiples tests usando suites de tests.
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