DEV Community

Cover image for JUnit Cómo repetir un test con parámetros
Ciro
Ciro

Posted on

JUnit Cómo repetir un test con parámetros

En publicaciones anteriores hemos visto de qué maneras se podía repetir la ejecución de un test, así como la manera de parametrizar un test.
En esta ocasión vamos a ver cómo unir ambas ideas para repetir un test parametrizado.

Utilizaremos para ello el mismo ejemplo de la publicación repetir la ejecución de un test, recuerdo que se trata de un método que genera un número aleatorio de N dígitos.

Inicialmente, puede que pensamos que es suficiente con combinar las anotaciones mencionadas en las otras publicaciones, @RepeatedTest + @ParameterizedTest, pero lamentablemente JUnit no soporta esta funcionalidad actualmente. Por fortuna la solución alternativa es muy simple.

Supongamos que partimos de un test parametrizado:

/**
 * Parameters:
 * 1. int - The lower bound.
 * 2. int - The upper bound.
 * 3. int - The number of digits of the random generated value.
 */
private static Stream<Arguments> randomNumberGeneratorParams() {
    return Stream.of(
        Arguments.of(1, 9, 1),
        Arguments.of(10, 99, 2),
        Arguments.of(100, 999, 3),
        Arguments.of(1000, 9999, 4),
        Arguments.of(10000, 99999, 5)
    );
}

@ParameterizedTest
@MethodSource(value = "randomNumberGeneratorParams")
@DisplayName(value = "Random numbers generator")
void random_numbers_generator(int low, int high, int numOfDigits) {    
    var actual = RandomUtil.generateNumber(numOfDigits);
    assertTrue(high >= actual, "Error, random is too high");
    assertTrue(low <= actual, "Error, actual is too low");
}

// Test passed: 5 of 5 ✅
// [1] low = 1, high = 9, numOfDigits = 1 -> numero generado 6
// [2] low = 10, high = 99, numOfDigits = 2 -> número generado 56
// [3] low = 100, high = 999, numOfDigits = 3 -> ...
// [4] low = 1000, high = 9999, numOfDigits = 4
// [5] low = 10000, high = 99999, numOfDigits = 5
Enter fullscreen mode Exit fullscreen mode

Podemos imaginar que este test no es muy fiable, ya que sólo hemos generado 1 número aleatorio para cada uno de nuestros casos de uso (generar un número de 1, 2, 3, 4 y 5 dígitos).

Para confirmar con seguridad que la función aleatoria es correcta, sería mejor si pudiéramos generar N números en cada rango o caso de uso, y comprobar que todos ellos cumplen con el test.

Veamos cómo hacerlo:

private static final int NUMBER_REPETITIONS = 1_000;

/**
 * Parameters:
 * 1. int - The lower bound.
 * 2. int - The upper bound.
 * 3. int - The number of digits of the random generated value.
 */
private static Stream<Arguments> randomNumberGeneratorParams() {
    return Stream.of(
        Arguments.of(1, 9, 1),
        Arguments.of(10, 99, 2),
        Arguments.of(100, 999, 3),
        Arguments.of(1000, 9999, 4),
        Arguments.of(10000, 99999, 5)
    );
}

@ParameterizedTest
@MethodSource(value = "randomNumberGeneratorParams")
@DisplayName(value = "Random numbers generator")
void random_numbers_generator(int low, int high, int numOfDigits) {
 int iterationCount = 1;
 do {   // <- Mediante el uso del loop do-while, podemos iterar la generación de los números aleatorios
     var actual = RandomUtil.generateNumber(numOfDigits);
     assertTrue(high >= actual, "Error, random is too high");
     assertTrue(low <= actual, "Error, actual is too low");
     iterationCount++;
 } while (iterationCount <= NUMBER_REPETITIONS);
}

// Test passed: 5 of 5 ✅
// [1] low = 1, high = 9, numOfDigits = 1 -> números generados: 6, 3, 1, 3, 4, 2, 6, 8, 9...1_000_000 de números generados
// [2] low = 10, high = 99, numOfDigits = 2 -> ...
// [3] low = 100, high = 999, numOfDigits = 3
// [4] low = 1000, high = 9999, numOfDigits = 4
// [5] low = 10000, high = 99999, numOfDigits = 5
Enter fullscreen mode Exit fullscreen mode

De esta manera, el test generará tantos números como indiquemos en NUMBER_REPETITIONS, y confirmará que todos ellos cumplen con las afirmaciones del test.

Oldest comments (0)