Seminario web destacado: Presentación de la prueba CT de Parasoft C/C++ para pruebas continuas y excelencia en el cumplimiento | Vea ahora

Aprovechando los beneficios de JUnit 5

Foto de cabeza de Brian McGlauflin,
6 de mayo de 2020
8 min leer

Además de ayudar a los desarrolladores a implementar pruebas unitarias en Java y mejorar la velocidad de programación, las pruebas JUnit ofrecen muchos beneficios. En esta publicación, se le explicarán estos beneficios y por qué debería usar las pruebas JUnit para su desarrollo.

Una versión de este artículo se publicó por primera vez en Blog de Oracle.

Han pasado algunos años desde el lanzamiento de Unidad 5. Si aún no ha comenzado a usarlo para sus pruebas de desarrollo, debería hacerlo. JUnit 5 viene con una multitud de nuevas funciones y mejoras que pueden ahorrarle tiempo y dolores de cabeza. Echemos un vistazo a cómo empezar con JUnit 5 para aprovechar los beneficios de la última tecnología.

Razones para migrar de JUnit 4 a JUnit 5

Si ha estado utilizando JUnit 4 durante un tiempo, la migración de pruebas puede parecer una tarea abrumadora. La buena noticia es que probablemente no necesite convertir ninguna prueba; JUnit 5 puede ejecutar pruebas JUnit 4 usando el Vintage biblioteca, por lo que puede comenzar a escribir nuevas pruebas con JUnit 5.

Aquí hay cuatro razones sólidas para comenzar a usar JUnit 5:

  • JUnit 5 aprovecha las características de Java 8 o posterior, como las funciones lambda, lo que hace que las pruebas sean más potentes y fáciles de mantener.
  • JUnit 5 ha agregado algunas características nuevas muy útiles para describir, organizar y ejecutar pruebas. Por ejemplo, las pruebas obtienen mejores nombres para mostrar y se pueden organizar jerárquicamente.
  • JUnit 5 está organizado en varias bibliotecas, por lo que solo se importan a su proyecto las funciones que necesita. Con sistemas de compilación como Maven y Gradle, incluir las bibliotecas adecuadas es fácil.
  • JUnit 5 puede usar más de una extensión a la vez, lo que JUnit 4 no podría (solo se puede usar un corredor a la vez). Esto significa que puede combinar fácilmente la extensión Spring con otras extensiones (como su propia extensión personalizada).

Cómo migrar a JUnit 5

Cambiar de JUnit 4 a JUnit 5 es bastante simple, incluso si tiene pruebas JUnit 4 existentes. La mayoría de las organizaciones no necesitan convertir JUnits antiguos a JUnit 5 a menos que se necesiten nuevas funciones.

  1. Actualice sus bibliotecas y compile sistemas de JUnit 4 a JUnit 5. Asegúrese de incluir el artefacto JUnit-vintage-engine en su ruta de tiempo de ejecución de prueba para permitir que se ejecuten sus pruebas existentes.
  2. Empiece a crear nuevas pruebas con las nuevas construcciones de JUnit 5.
  3. (Opcional) Convierta las pruebas JUnit 3 y JUnit 4 a JUnit 5.

Diferencias importantes entre JUnit 5 y JUnit 4

Las pruebas de JUnit 5 se ven prácticamente iguales a las de JUnit 4, pero hay algunas diferencias que debe tener en cuenta.

Importaciones

JUnit 5 usa el nuevo org.JUnit.jupiter paquete para sus anotaciones y clases. Por ejemplo, org.JUnit.Prueba se convierte en org.JUnit.jupiter.api.Test.

Anotaciones

El @Prueba la anotación ya no tiene parámetros; cada uno de estos se ha movido a una función. Por ejemplo, para indicar que se espera que una prueba lance una excepción en JUnit 4:

En JUnit 5, esto ha cambiado a:

Del mismo modo, los tiempos de espera han cambiado. En JUnit 4, se veían así:

En JUnit 5, los tiempos de espera se ven así:

Aquí hay otras anotaciones que han cambiado:

  • @Antes se ha convertido @AntesEach
  • @Después se ha convertido @Después de cada
  • @Antes de clase se ha convertido @Antes de todo
  • @Después de clases se ha convertido @Después de todo
  • @Ignorar se ha convertido @Discapacitado
  • @Categoría se ha convertido @Etiqueta
  • @Regla y @ReglaDeClase se han ido — usa @ExtenderCon y @registrarextensión

Aserciones

Las afirmaciones de JUnit 5 ahora están en org.JUnit.jupiter.api.Aserciones. La mayoría de las afirmaciones comunes, como asertEquals () y asertNotNull () tienen el mismo aspecto que antes, pero hay algunas diferencias clave:

  • El mensaje de error es ahora el último argumento, por ejemplo: asertEquals ("mi mensaje", 1, 2) sería asertEquals (1, 2, "mi mensaje")
  • La mayoría de las aserciones ahora aceptan una lambda que construye el mensaje de error, que solo se llama cuando falla la aserción.
  • asertTimeout () y assertTimeoutPreemptively () han reemplazado el @Se acabó el tiempo anotación (tenga en cuenta que hay una anotación @Timeout en JUnit 5, pero funciona de manera diferente a JUnit 4).
  • Hay varias afirmaciones nuevas, que se describen a continuación.

Tenga en cuenta que puede seguir usando afirmaciones de JUnit 4 en una prueba de JUnit 5 si lo prefiere.

Supuestos

Las suposiciones se han trasladado a org.JUnit.jupiter.api.Supuestos.

Existen las mismas suposiciones, pero ahora apoyan Proveedor booleano así como los igualadores Hamcrest para adaptarse a las condiciones. Se pueden usar lambdas (de tipo ejecutable) para que el código se ejecute cuando se cumpla la condición.

Aquí hay un ejemplo en JUnit 4:

En JUnit 5, se convierte en esto:

Extendiendo JUnit

En JUnit 4, personalizar el marco generalmente significaba usar un @Corre con anotación para especificar un corredor personalizado. El uso de varios corredores era problemático y, por lo general, requería encadenar o usar un @Regla. Esto se ha simplificado y mejorado en JUnit 5 usando extensiones.

Por ejemplo, la creación de pruebas con el marco Spring se veía así en JUnit 4:

Con JUnit 5, incluye Spring Extension en su lugar:

El @ExtenderCon La anotación es repetible, lo que significa que se pueden combinar fácilmente varias extensiones.
Usted También podemos definir nuestras propias extensiones personalizadas fácilmente creando una clase que implemente una o más interfaces de org.JUnit.jupiter.api.extensióny luego agregarlo a nuestra prueba con @ExtenderCon.

 

Conversión de pruebas a JUnit 5

Para convertir una prueba JUnit 3 o JUnit 4 existente a JUnit 5, los siguientes pasos deberían funcionar para la mayoría de las pruebas:

  1. Actualice las importaciones para eliminar JUnit 4 y agregar JUnit 5. Por ejemplo, actualice el nombre del paquete para el @Prueba anotación, y tanto el paquete como el nombre de la clase para las aserciones (de Afirma a Aserciones). No se preocupe todavía si hay errores de compilación, completar los siguientes pasos debería resolverlos.
  2. Reemplace globalmente las anotaciones antiguas y los nombres de clases por otros nuevos. Por ejemplo, reemplace todos @Antes @AntesEach, Y todos Afirma Aserciones.
  3. Actualice las afirmaciones. Cualquier afirmación que proporcione un mensaje debe tener el argumento del mensaje movido al final. ¡Preste especial atención cuando los tres argumentos sean cadenas! Además, actualice los tiempos de espera y las excepciones esperadas (consulte los ejemplos anteriores).
  4. Actualice las suposiciones si las está utilizando.
  5. Reemplazar cualquier instancia de @Corre con, @Reglao @ReglaDeClase con el apropiado @ExtenderCon anotaciones. Es posible que necesite encontrar documentación actualizada en línea para las extensiones que está utilizando como ejemplos.

Tenga en cuenta que la migración de pruebas parametrizadas requerirá un poco más de refactorización, especialmente si ha estado usando JUnit 4 Parametrizado (el formato de las pruebas parametrizadas JUnit 5 está mucho más cerca de Parámetros JUnit).

Nuevas características

Hasta ahora, he analizado solo la funcionalidad existente y cómo ha cambiado. Pero JUnit 5 ofrece muchas características nuevas para hacer que nuestras pruebas sean más descriptivas y fáciles de mantener.

Mostrar nombres

Con JUnit 5, puede agregar el @Nombre para mostrar anotación a clases y métodos. El nombre se usa al generar informes, lo que facilita la descripción del propósito de las pruebas y el seguimiento de fallas, por ejemplo:

También puede usar un generador de nombres para mostrar para procesar su clase de prueba y / o método para generar nombres de prueba en cualquier formato que desee. Consulte la documentación de JUnit para obtener detalles y ejemplos.

Aserciones

JUnit 5 introdujo algunas afirmaciones nuevas, como:

  • asertIterableEquals () realiza una verificación profunda de dos iterables, utilizando equals ()
  • asertLinesMatch () verifica que coincidan dos listas de cadenas; acepta expresiones regulares en el argumento "esperado".
  • asertAll () agrupa varias afirmaciones juntas. El beneficio adicional es que se realizan todas las afirmaciones, incluso si fallan las afirmaciones individuales.
  • asertThrows () y asertDoesNotThrow () han reemplazado el esperado propiedad en el @Prueba anotación

Pruebas anidadas

Los conjuntos de pruebas en JUnit 4 fueron útiles, pero las pruebas anidadas en JUnit 5 son más fáciles de configurar y mantener, y describen mejor las relaciones entre los grupos de prueba, por ejemplo:

En el examplio arriba, puedes ver que I utilizar una sola clase para todas las pruebas relacionadas con Myclass. I puede verificar que la clase es instanciable en la clase de prueba externa, y I use una clase interna anidada para todas las pruebas donde Myclass se instancia e inicializa. los @AntesEach El método solo se aplica a las pruebas en la clase anidada.

El @MostrarNombres Las anotaciones para las pruebas y las clases indican tanto el propósito como la organización de las pruebas. Esto ayuda a comprender el informe de prueba porque Usted can ver las condiciones en las que se realiza la prueba (Verificar MyClass con inicialización) y lo que está verificando la prueba (mimétodo devuelve verdadero). Este es un buen patrón de diseño de prueba para JUnit 5.

Pruebas parametrizadas

La parametrización de prueba existía en JUnit 4 con bibliotecas integradas como JUnit4 Parametrizado o bibliotecas de terceros como Parámetros JUnit. En JUnit 5, las pruebas parametrizadas están completamente integradas y adoptan algunas de las mejores características de JUnit4 Parametrizado y Parámetros JUnit, Por ejemplo:

El formato se parece a Parámetros JUnit, donde los parámetros se pasan directamente al método de prueba. Tenga en cuenta que los valores para probar pueden provenir de varias fuentes diferentes. Aquí, solo tengo un solo parámetror por lo que es fácil de usar @FuenteValor. @FuenteVacío y @Fuente nula para indicar que I desea agregar una cadena vacía y un nulo a la lista de valores para ejecutar, respectivamente (y usted puede combinarlos, como arriba, si usa ambos). Hay muchas otras fuentes de valor, como @EnumSource y @ArgumentosFuente (un proveedor de valor personalizado). Si necesita más de un parámetro, también puede usar @MétodoFuente or @CsvFuente. Consulte la documentación de JUnit 5 para obtener más detalles y ejemplos..

Otro tipo de prueba agregado en JUnit 5 es @RepetidoPrueba, donde una sola prueba se repite un número específico de veces.

Ejecución de prueba condicional

JUnit 5 proporciona Condición de ejecución API de extensión para habilitar o deshabilitar una prueba o contenedor (clase de prueba) condicionalmente. Esto es como usar @Discapacitado en una prueba, pero puede definir condiciones personalizadas. Hay varias condiciones integradas, como:

  • @EnabledOnOs y @DisabledOnOs: Habilita una prueba solo en los sistemas operativos especificados.
  • @EnabledOnJre y @Discapacitado: Especifica que la prueba debe habilitarse o inhabilitarse para versiones específicas de Java.
  • @EnabledIfSystemProperty: Habilita una prueba basada en el valor de una propiedad del sistema JVM.
  • @EnabledIf: Utiliza lógica con script para habilitar una prueba si se cumplen las condiciones del script.

Plantillas de prueba

Las plantillas de prueba no son pruebas regulares. Definen un conjunto de pasos a realizar, que luego se pueden ejecutar en otro lugar utilizando un contexto de invocación específico. Esto significa que puede definir una plantilla de prueba una vez y luego crear una lista de contextos de invocación en tiempo de ejecución para ejecutar esa prueba. Encuentre más detalles y ejemplos en la documentación de Junit 5.

Pruebas dinámicas

Las pruebas dinámicas son como plantillas de prueba: las pruebas a ejecutar se generan en tiempo de ejecución. Sin embargo, mientras que las plantillas de prueba se definen con un conjunto específico de pasos y se ejecutan varias veces, las pruebas dinámicas usan el mismo contexto de invocación pero pueden ejecutar una lógica diferente. Un uso de las pruebas dinámicas sería transmitir una lista de objetos abstractos y realizar un conjunto separado de afirmaciones para cada uno en función de sus tipos concretos. Para obtener buenos ejemplos, consulte la documentación de Junit 5.

Conclusión

JUnit 5 es una actualización potente y flexible del marco JUnit. Proporciona una variedad de mejoras y nuevas funciones para organizar y describir casos de prueba, además de ayudar a comprender los resultados de las pruebas. La actualización a JUnit 5 es rápida y fácil: solo actualice las dependencias de su proyecto y comience a usar las nuevas funciones.

¿Quiere ver cómo simplificar la creación de casos de prueba JUnit y stubs/simulacros asociados con Unit Test Assistant de Jtest?