Cómo cambiar el orden de los tests de JUnit 5 (aunque no deberías)

El orden de ejecución de los tests en JUnit es importante. Existe una razón por la cual en JUnit los tests no siempre se ejecutan de arriba a abajo, y por otra parte también es importante saber por qué es buena razón respetar esto y no hacer tests que dependan de un orden de ejecución concreto. Dicho eso, JUnit tiene mecanismos para cambiar el orden de ejecución, que es lo que te voy a contar en esta lección.

Cuando trabajamos con JUnit 5, una cuestión que a menudo surge es el orden en el que se ejecutan los tests dentro de una suite. Por defecto, JUnit no garantiza un orden específico, y esto es intencionado para fomentar que cada test sea independiente y confiable sin importar cuándo se ejecute. Para ilustrar esto, podemos crear una clase de tests que simplemente imprima mensajes en consola para observar el orden de ejecución.

Al ejecutar una suite con varios métodos de test, veremos que el orden no coincide ni con el orden en que están escritos en el código ni con un orden alfabético. Por ejemplo, si tenemos tres tests llamados testMétodo, testEjemplo y testCaso, la ejecución podría ser en el orden testEjemplo, testCaso y luego testMétodo. Esto demuestra que JUnit reorganiza los tests de forma arbitraria, lo que nos asegura que no debemos depender de un orden específico para que los tests funcionen correctamente.

Esta independencia es fundamental porque permite ejecutar cada test de forma aislada, sin necesidad de que otro test se haya ejecutado antes. Esto es especialmente útil cuando tenemos suites grandes y queremos ejecutar solo un test específico sin esperar a que se ejecuten todos los demás. Si los tests no fueran independientes, tendríamos problemas para mantener la suite y para detectar fallos de forma precisa.

Sin embargo, en algunas situaciones concretas, como en tests de integración donde ciertas operaciones deben ocurrir en un orden específico (por ejemplo, iniciar sesión antes de interactuar con la interfaz), puede ser necesario controlar el orden de ejecución. Para estos casos, JUnit 5 ofrece la anotación @TestMethodOrder, que se aplica a nivel de clase y permite definir la estrategia para ordenar los métodos de test.

Esta anotación recibe como parámetro una clase que implementa la estrategia de ordenación. Entre las opciones más comunes están:

  • MethodOrderer.Alphanumeric.class: ordena los tests alfabéticamente según el nombre del método. Por ejemplo, si aplicamos esta estrategia a los métodos testCaso, testEjemplo y testMétodo, se ejecutarán en ese orden alfabético.

  • MethodOrderer.OrderAnnotation.class: permite definir un orden manual mediante la anotación @Order en cada método de test. Por ejemplo, podemos asignar @Order(1) a testEjemplo, @Order(2) a testMétodo y @Order(3) a testCaso. JUnit ejecutará los tests siguiendo esta numeración, del menor al mayor.

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class LifecycleTest {

    @Test
    @Order(1)
    void testEjemplo() {
        System.out.println("Ejecutando testEjemplo");
    }

    @Test
    @Order(2)
    void testMétodo() {
        System.out.println("Ejecutando testMétodo");
    }

    @Test
    @Order(3)
    void testCaso() {
        System.out.println("Ejecutando testCaso");
    }
}

Si algún método no tiene la anotación @Order, JUnit lo ejecutará después de los que sí la tienen, sin un orden garantizado entre ellos.

  • MethodOrderer.Random.class: fuerza a que el orden de ejecución sea aleatorio en cada ejecución, incluso si no se hacen cambios en el código. Esto puede ser útil para detectar dependencias ocultas entre tests que solo fallan cuando se ejecutan en cierto orden.
@TestMethodOrder(MethodOrderer.Random.class)
class LifecycleTest {

    @Test
    void testEjemplo() {
        System.out.println("Ejecutando testEjemplo");
    }

    @Test
    void testMétodo() {
        System.out.println("Ejecutando testMétodo");
    }

    @Test
    void testCaso() {
        System.out.println("Ejecutando testCaso");
    }
}

Cada vez que ejecutemos esta clase, el orden de los tests cambiará de forma impredecible.

En definitiva, aunque JUnit 5 nos permite controlar el orden de ejecución de los tests mediante estas anotaciones, lo más recomendable es diseñar tests que sean completamente independientes y que no requieran un orden específico para funcionar correctamente. Esto facilita el mantenimiento, mejora la fiabilidad y permite ejecutar tests de forma aislada sin sorpresas. Solo en casos muy concretos, como tests de integración con dependencias claras, deberíamos recurrir a modificar el orden de ejecución.

Lista de reproducción
  1. 1
    ¿Qué es una prueba unitaria? ¿Me vale con crear un main?
    7 minutos
  2. 2
    Cómo crear tests unitarios con JUnit 5
    17 minutos
  3. 3
    Cómo usar BeforeEach, AfterEach, BeforeAll y AfterAll en JUnit 5
    11 minutos
  4. 4
    Cómo cambiar el orden de los tests de JUnit 5 (aunque no deberías)
    8 minutos
  5. 5
    Cómo aprovechar la clase Assertions de JUnit 5
    8 minutos
  6. 6
    Cómo ejecutar tests condicionalmente en JUnit 5
    7 minutos
  7. 7
    Cómo hacer tests de excepciones en JUnit 5 con assertThrows
    5 minutos
  8. 8
    Cómo crear Nested tests en JUnit 5 (un test dentro de otro)
    5 minutos
  9. 9
    Cómo configurar y crear tests de JUnit 5 en NetBeans
    6 minutos
  10. 10
    Cómo configurar y crear tests de JUnit 5 en Eclipse
    5 minutos
  11. 11
    Cómo configurar y crear tests de JUnit 5 en IntelliJ IDEA
    4 minutos