Cómo ejecutar tests condicionalmente en JUnit 5

Si tenemos tests que sólo se deberían ejecutar en condiciones concretas, por ejemplo, en versiones específicas de la máquina virtual de Java, o en sistemas operativos concretos, podemos utilizar un conjunto de anotaciones específicas para limitar la ejecución de un test a una serie de plataformas opcionales. Además, mediante las funciones de tipo Assume, podemos crear nuestros propios checks dinámicos que hacen que se salte lo que queda de un test cuando no se cumpla una condición especificada.

En ocasiones, cuando trabajamos con pruebas en JUnit 5, nos encontramos con la necesidad de saltarnos ciertos tests. Esto puede deberse a que sabemos que un test está fallando por una razón conocida y queremos omitirlo temporalmente para no bloquear el resto del desarrollo. Para estos casos, JUnit 5 nos ofrece una forma sencilla y directa: la anotación @Disabled. Al aplicarla sobre un test, indicamos que ese test no debe ejecutarse, y así evitamos que falle y afecte a la suite completa. Además, podemos añadir un mensaje explicativo dentro de la anotación para dejar constancia del motivo por el cual se está desactivando, lo que resulta útil para nosotros mismos o para otros miembros del equipo.

Pero a veces no basta con desactivar un test de forma fija; puede que queramos que la ejecución dependa de ciertas condiciones, como el sistema operativo en el que estamos trabajando, la versión de Java que usamos o incluso el entorno en el que se ejecutan las pruebas, como un servidor de integración continua. Para estos escenarios, JUnit 5 nos proporciona una familia de anotaciones que comienzan con @Enabled y @Disabled, que nos permiten controlar la ejecución de tests según condiciones específicas.

Por ejemplo, con @EnabledOnOs podemos indicar que un test solo se ejecute si estamos en un sistema operativo determinado, como Windows o Mac. Si el sistema operativo no coincide, el test se saltará automáticamente. De forma similar, @EnabledOnJre nos permite restringir la ejecución a ciertas versiones del runtime de Java, aunque hay que tener en cuenta que esta funcionalidad puede no ser completamente fiable debido a las múltiples versiones y distribuciones existentes. También podemos usar @DisabledOnOs o @DisabledOnJre para evitar que un test se ejecute en determinados entornos o versiones.

Estas anotaciones son muy útiles para adaptar nuestras pruebas a entornos variados sin necesidad de modificar el código de los tests, simplemente añadiendo las condiciones que consideremos necesarias.

Sin embargo, si queremos un control aún más fino y dinámico sobre cuándo ejecutar o saltar un test, podemos recurrir a las asunciones que ofrece JUnit 5. Las asunciones funcionan evaluando una condición booleana antes de ejecutar el test, y si la condición no se cumple, el test se omite. Esto es especialmente útil cuando la ejecución depende de condiciones que solo podemos evaluar en tiempo de ejecución.

Las principales asunciones que podemos usar son assumeTrue, assumeFalse y assumingThat. Con assumeTrue indicamos que el test solo debe ejecutarse si la condición es verdadera; si no, se salta. Por el contrario, assumeFalse hace que el test se ejecute solo si la condición es falsa. Por último, assumingThat nos permite ejecutar un bloque de código condicionalmente, dependiendo de si la condición es verdadera, sin afectar al resto del test.

Veamos un ejemplo sencillo para ilustrar cómo funcionan estas asunciones:

import static org.junit.jupiter.api.Assumptions.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

public class CondicionalTest {

    @Test
    void testConAssumeTrue() {
        assumeTrue(2 + 2 == 4);
        // Esta asunción es verdadera, por lo que el test continúa y puede fallar o pasar
        assertEquals(5, 2 + 2); // Este test fallará porque 2+2 no es 5
    }

    @Test
    void testConAssumeTrueQueFalla() {
        assumeTrue(2 + 2 == 5);
        // Esta asunción es falsa, por lo que el test se saltará y no se ejecutará el assert
        assertEquals(5, 2 + 2);
    }

    @Test
    void testConAssumingThat() {
        assumingThat(2 + 2 == 4, () -> {
            // Este bloque solo se ejecuta si la condición es verdadera
            assertEquals(4, 2 + 2);
        });
        // Aquí podríamos tener más código que se ejecuta siempre
    }
}

En este código, el primer test se ejecuta porque la asunción es verdadera, aunque el test falla porque la suma no es 5. El segundo test se salta porque la asunción es falsa, evitando así un fallo innecesario. El tercer test ejecuta el bloque condicional solo si la condición se cumple, permitiéndonos controlar partes específicas del test.

Estas asunciones nos permiten crear tests que se adaptan a condiciones dinámicas, como la presencia de ciertos recursos, configuraciones del entorno o cualquier otra variable que pueda influir en la validez del test.

En definitiva, JUnit 5 nos ofrece varias herramientas para gestionar la ejecución condicional de tests, desde la simple anotación @Disabled para desactivar tests conocidos que fallan, pasando por las anotaciones @Enabled y @Disabled para condiciones estáticas basadas en el entorno, hasta las asunciones para un control más dinámico y flexible en tiempo de ejecución. Así podemos mantener nuestras suites de pruebas limpias, eficientes y adaptadas a las necesidades reales de nuestro proyecto.

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