sábado, 9 de diciembre de 2017

JUnit 5: Nuevas caracteristicas - 1

Hace poco ha salido JUnit 5 y dado que últimamente estamos haciendo muchos posts sobre tests, vamos ha hacer una serie sobre lo que trae esta nueva versión.
JUnit 5 se dividie en 3 módulos: JUnit Platform + JUnit Jupiter + JUnit Vintage. El primero nos provee del servidor para ejecutar las pruebas en la JVM y de la API. Jupiter es el módulo de extensión y nuevas caracteristicas que nos permite desarrollar los tests. Y el último es el módulo que nos permite implementar tests de antiguas versiones. 
  • Nuevas anotaciones
    • @Before y @After ahora son @BeforeEach y @AfterEach
    • @Before/AfterClass ahora son @Before/AfterAll
    • @Ignore es @Disabled
    • @Category es @Tag
Y además ahora también hay una anotación @Test en la nueva paquetería. Y @DisplayName que nos permite dar un título a nuestros tests.
Mantiene los de JUnit 4 y añade algunas más. Además incluye soporte para Lambda.
En la parte de las aserciones también tenemos la novedad de la agrupación. Con 'assertAll' nos permitirá realizar varias pruebas y además ver el resultado de todas ellas, no solo de la primera.

@Test
void groupedAssertions() {
    assertAll("person",
        () -> assertEquals("John", person.getFirstName()),
        () -> assertEquals("Doe", person.getLastName())
    );
}

@Test
void testOnlyOnCiServer() {
    assumeTrue("CI".equals(System.getenv("ENV")));
}
Ahora podemos complicar la ejecución de las pruebas, pudiendo relacionar diferentes grupos de pruebas. Para ello debemos crear un test y seguidamente una clase interna con la anotación 'Nested'. Dentro de esta clase interna, podremos desarrollar más pruebas. Las cuales se ejecutarán de forma anidada a la prueba que le antecedía. 

@Test
@DisplayName("is instantiated with new Stack()")
void isInstantiatedWithNew() {
    new Stack<>();
}
@Nested
@DisplayName("when new")
class WhenNew {
    @Test
    @DisplayName("is empty")
    void isEmpty() {
        assertTrue(stack.isEmpty());
    }
}
Ahora también podemos usar anotaciones (@Test, @RepeatedTest, @ParameterizedTest, @TestFactory, @TestTemplate, @BeforeEach, y @AfterEach) y crear métodos asociados a dichas anotaciones en las interfaces. 
Posteriormente spodemos ejecutar una clase que tenga implemente dicha interfaz. De esta forma, se ejecutarán dichos métodos en base creados en la interfaz.

interface TestLifecycleLogger {
    @BeforeAll
    default void beforeAllTests() {
        LOG.info("Before all tests");
    }
}
class TestInterfaceDemo implements TestLifecycleLogger {
    @Test
    void isEqualValue() {
        assertEquals(1, 1, "is always equal");
    }
}

Con este ejemplo, al ejecutar la clase 'TestInterfaceDemo', veremos en consola primero el mensaje 'Before all tests'  y luego 'is always equal'.

En siguientes post hablaremos de nuevas mejoras que trae JUnit 5 como son: repetición de tests, tests parametrizados y tests dinámicos. O de su modelo de extensión que nos permite hacer cosas como: ejecuciones condicionales, mejora en el manejo de excepciones o el registro de extenciones (donde la extensión 'ExtendWith', la cual acaba con las extensiones 'Rule' y 'ClassRule').

No hay comentarios:

Publicar un comentario