JUnit es un marco de automatización de pruebas para el lenguaje de programación Java . JUnit se utiliza a menudo para pruebas unitarias y es uno de los marcos xUnit .
JUnit se vincula como un JAR en tiempo de compilación. La última versión del marco, JUnit 5, se encuentra en el paquete org.junit.jupiter
. [3] Las versiones anteriores JUnit 4 [3] y JUnit 3 se encontraban en los paquetes org.junit
y junit.framework
, respectivamente.
Una encuesta de investigación realizada en 2013 en 10 000 proyectos Java alojados en GitHub reveló que JUnit (junto con slf4j-api ) era la biblioteca externa incluida con mayor frecuencia. El 30,7 % de los proyectos utilizaba cada biblioteca. [4]
Cada clase de prueba JUnit suele tener varios casos de prueba. Estos casos de prueba están sujetos al ciclo de vida de la prueba. El ciclo de vida completo de JUnit tiene tres fases principales: [5]
@BeforeAll
anotación. El otro tipo se configura antes de ejecutar cada caso de prueba, que utiliza la @BeforeEach
anotación. [5]@Test
Aquí se utiliza la anotación. [5]@AfterAll
anotación se utiliza para respaldar la limpieza a nivel de clase. La @AfterEach
anotación permite la limpieza después de la ejecución de la prueba. [5]JUnit 5 integra una serie de herramientas, como herramientas de compilación , entornos de desarrollo integrados (IDE), herramientas de integración continua (CI) y muchas más. [6]
JUnit es compatible con las herramientas de compilación Apache Ant , Apache Maven y Gradle , que son las herramientas de compilación de proyectos más utilizadas. [7] Las herramientas de compilación son vitales para automatizar el proceso de compilación del proyecto. [6]
Apache Ant, también conocido como Ant, es una de las herramientas de compilación con el mayor grado de versatilidad y tiene la historia más larga de las tres herramientas de compilación enumeradas anteriormente. [8] Ant se centra en el build.xml
archivo, que se utiliza para configurar las tareas necesarias para ejecutar un proyecto. [8] Ant también tiene una extensión llamada Apache Ivy , que ayuda a lidiar con la resolución de dependencias. Las dependencias del proyecto se pueden declarar en el ivy.xml
archivo. Ant puede integrarse con JUnit 5 configurando las herramientas de cobertura de código Java (JaCoCo), para el ivy.xml
archivo. [8] Luego se ivy.xml
puede configurar con las dependencias java-platform-console
y junit-platform-runner
para integrarse con JUnit 5. [9]
A diferencia de Ant, Apache Maven, también conocido como Maven, utiliza un enfoque estandarizado y unificado para el proceso de compilación. [10] Maven sigue el paradigma de "convención sobre configuración" para administrar sus dependencias. [11] El código fuente de Java (o "src") se puede encontrar en el src/main/java
directorio, y los archivos de prueba se pueden encontrar en el src/test/java
directorio. [11] Maven se puede utilizar para cualquier proyecto Java. [10] Utiliza el Modelo de objetos de proyecto (POM), que es un enfoque basado en XML para configurar los pasos de compilación para el proyecto. [10] El Maven mínimo con el pom.xml
archivo de compilación debe contener una lista de dependencias y un identificador de proyecto único. [10] Maven debe estar disponible en la ruta de compilación para funcionar. [10] Maven se puede integrar con JUnit 5 utilizando el jacoco-maven-plugin
complemento que admite la funcionalidad lista para usar para las pruebas de JUnit 5. [12] Se pueden especificar diferentes objetivos de Maven para lograr estas tareas. [12]
Gradle es una herramienta de compilación que toma prestados muchos conceptos de sus predecesores, Ant y Maven. [11] Utiliza el build.gradle
archivo para declarar los pasos necesarios para la compilación del proyecto. [11] A diferencia de Ant y Maven, que están basados en XML, Gradle requiere el uso de Apache Groovy , que es un lenguaje de programación basado en Java. [11] A diferencia de Ant y Maven, Gradle no requiere el uso de XML. [11] Gradle todavía se adhiere al enfoque de "convención sobre configuración" de Maven, y sigue la misma estructura para los directorios src/main/java
y src/test/java
. [11] Gradle puede integrarse con JUnit 5 configurando un complemento jacoco
junto con el complemento junit-platform proporcionado por el equipo de JUnit 5 en el archivo de compilación. [13]
JUnit sigue el paradigma de preferir los puntos de extensión por sobre las características. [14] El equipo de JUnit decidió no poner todas las características dentro del núcleo de JUnit, y en su lugar decidió brindar una forma extensible para que los desarrolladores aborden sus inquietudes. [14]
En JUnit 4, hay dos mecanismos de extensión: la API Runner y la API Rule. [15] Había algunas desventajas tanto en la API Runner como en la API Rule.
Una limitación importante de la API Runner es que el desarrollador tiene que implementar todo el ciclo de vida, incluso si solo necesita una etapa específica del ciclo de vida. [15] Esto es demasiado complicado y pesado para la mayoría de los casos de uso. [15] Otra limitación importante es que solo se utiliza una clase de ejecutor para cada caso de prueba, y los hace incomponibles. [15] Como ejemplo, Mockito y los ejecutores parametrizados no pueden existir dentro de la misma clase de prueba. [15]
Una limitación importante de la API de reglas es que no puede controlar todo el ciclo de vida de la prueba, por lo que no se pueden usar para cada caso de uso individual. [15] Solo son apropiadas cuando algo debe ocurrir antes o después de la ejecución del caso de prueba. [15] Otra limitación importante es que las reglas para las devoluciones de llamadas a nivel de clase y a nivel de método deben crearse por separado. [15]
En JUnit 5, la API de extensión se encuentra dentro del JUnit Jupiter Engine. [16] El equipo de JUnit quiere permitir que el desarrollador se conecte a etapas separadas de un ciclo de vida de prueba al proporcionar una única API de extensión unificada. [16] Al llegar a una determinada fase del ciclo de vida, el Jupiter Engine invocará todas las extensiones registradas para esa fase. [16] El desarrollador puede conectarse a cinco puntos de extensión principales: [16]
Un elemento de prueba JUnit es un objeto Java. Los métodos de prueba deben estar anotados con la @Test
anotación . Si la situación lo requiere, [21] también es posible definir un método para que se ejecute antes (o después) de cada (o todos) los métodos de prueba con las anotaciones @BeforeEach
(o @AfterEach
) y @BeforeAll
(o @AfterAll
). [22] [23]
importar org.junit.jupiter.api.* ; clase FoobarTests { @BeforeAll static void setUpClass () lanza Exception { // Código ejecutado antes del primer método de prueba } @BeforeEach void setUp () lanza Exception { // Código ejecutado antes de cada prueba } @Test void oneThing () { // Código que prueba una cosa } @Test void anotherThing () { // Código que prueba otra cosa } @Test void somethingElse () { // Código que prueba algo más } @AfterEach void tearDown () throws Exception { // Código ejecutado después de cada prueba } @AfterAll static void tearDownClass () throws Exception { // Código ejecutado después del último método de prueba } }
Según Martin Fowler, uno de los primeros en adoptar JUnit: [24]
JUnit nació en un vuelo de Zurich a la OOPSLA de 1997 en Atlanta. Kent volaba con Erich Gamma, y ¿qué otra cosa podían hacer dos geeks en un vuelo largo sino programar? La primera versión de JUnit se construyó allí, se programó en pares y se hizo la prueba primero (una forma agradable de geek metacircular).
Como efecto secundario de su amplio uso, las versiones anteriores de JUnit siguen siendo populares, y JUnit 4 tiene más de 100 000 usos por otros componentes de software en el repositorio Maven Central. [25]
En JUnit 4, las anotaciones para las devoluciones de llamadas de ejecución de pruebas eran @BeforeClass
, @Before
, @After
, y @AfterClass
, a diferencia de las @BeforeAll
, , @BeforeEach
, @AfterEach
y @AfterAll
, de JUnit 5. [22] [23]
En JUnit 3, los accesorios de prueba tenían que heredar de junit.framework.TestCase
. [26] Además, los métodos de prueba tenían que tener el prefijo 'test' como prefijo. [27]