JUnit es un marco de pruebas unitarias de código abierto de terceros. El proyecto fue iniciado por Kent Beck y Erich Gamma a fines de 1995. Rápidamente atrajo el interés de la comunidad de desarrolladores que se ocupan particularmente del desarrollo basado en pruebas. JUnit se introdujo inicialmente en Smalltalk, pero luego se transfirió a Java, que rápidamente lo adoptó como un estándar de facto de prueba unitaria. La popularidad de JUnit creció hasta el punto de que, para satisfacer las necesidades de muchos otros lenguajes contemporáneos como C#, Perl, Python, PHP, Ruby, Visual Basic, C++, etc., se desarrolló un marco xUnit genérico donde la letra 'x' se reemplaza por la primera letra del lenguaje, como JUnit para Java, RUnit para Ruby, etc. Este artículo proporciona una descripción general de este marco utilizado por el estándar de facto de las pruebas unitarias de Java.
Descripción general de las pruebas
La prueba es una fase importante en el ciclo de vida del desarrollo de una aplicación. El objetivo principal de las pruebas es evaluar un programa sobre la base de las especificaciones requeridas. El objetivo es crear ciertos casos de prueba que muestren errores, brechas, discrepancias o resultados inesperados, tanto como sea posible. Este concepto simple tiene algunos procesos elaborados asociados con él. Pero, para decirlo brevemente, se hace en tres niveles. Cuando la prueba se realiza a un nivel muy granular o de componente individual, se denomina Prueba unitaria.; cuando se combinan para comprobar las interfaces entre los componentes con respecto a un diseño de software, se denominan Pruebas de integración.; y finalmente, cuando se integra el sistema completo y se realizan pruebas para verificar que el sistema en su conjunto cumple con el requisito especificado, se denomina Prueba del sistema. .
Pruebas unitarias
En pocas palabras, realizar una prueba unitaria es una forma de examinar el comportamiento de una unidad de código distinta. En Java, una unidad de código puede significar un método o una clase o incluso un módulo, según el contexto. Si es un método, por ejemplo, el enfoque de la prueba está en evaluar la referencia de objeto correcta permitida para invocar el método, tipo de parámetros y valores aceptables, rangos de valores primitivos, tipo y valor de retorno, etc. La idea es asar a la parrilla el método para que pueda hacerse lo suficientemente robusto como para manejar su problema con gracia y descartar aquellos que están más allá de su alcance aparte de cumplir con su contrato.
Por lo tanto, las pruebas unitarias forman el bloque de construcción básico de cualquier evaluación de programa. De hecho, cada programador realiza algún tipo de prueba unitaria mientras escribe el código para verificar el resultado del código con algunos datos/casos ficticios. Las pruebas unitarias son, por lo tanto, un estatus formal dado a esa colección aislada de pruebas. Es extremadamente importante que un código pase por el rigor de varias fases de prueba. Las pruebas unitarias, aparte de su importancia, también son muy habituales. Personas como Kent Beck y Erich Gamma pensaron en crear un marco para que los programadores obtengan un entorno estructurado y puedan automatizar muchas de estas tareas. Después de todo, para eso está el framework. Por lo general, proporciona una estructura de programa coherente que se puede reutilizar y compartir entre aplicaciones. Un programador puede incorporarlos en una aplicación existente y ampliarlos según sus necesidades específicas.
Un ejemplo rápido
Un código de prueba de unidad simple para examinar el método único en Temperatura La clase sin usar el marco JUnit es la siguiente:
package org.mano.unittest.examples; public class Circle { double area(double radius) { returnMath.PI* radius * radius; } }
Ahora, escribamos el código para probar unitariamente el área método.
package org.mano.unittest.examples; public class CircleTest { public int errCounter= 0; public void testCircleArea() { Circle circle = new Circle(); double area = circle.area(12); if (area < 452 && area > 453) { throw new IllegalStateException("Wrong calculation!: " + area); } } public static void main(String[] args) { TestCircle test = new TestCircle(); try { test.testCircleArea(); } catch (Throwable e) { test.errCounter++; e.printStackTrace(); } if (test.errCounter> 0) { throw new IllegalStateException("There were " + test.errCounter+ " error(s)"); } } }
Este es un ejemplo rudimentario, pero le da una idea de cómo se pueden realizar las pruebas unitarias sin usar ningún marco.
Marco de pruebas JUnit
Usar el framework JUnit para pruebas unitarias tiene varias ventajas. Proporciona numerosas anotaciones que facilitan la escritura y ejecución de códigos de prueba en Java:
- Principalmente, separa la preocupación de las pruebas unitarias del código real del proyecto al permitirle crear una instancia de clase de prueba y cargadores de clases para cada prueba unitaria. Estos "inmunen" al código existente de los efectos secundarios innecesarios de las pruebas.
- Las anotaciones proporcionadas por JUnit, como @Before, @After, @BeforeClass, @AfterClass —tener métodos tanto para la inicialización de recursos como para la recuperación de recursos.
- Existe una amplia variedad de métodos de afirmación para verificar el resultado de una prueba.
- A lo largo de los años, JUnit se volvió tan popular que numerosas herramientas de Java, como Ant y Maven; e IDE populares, como Eclipse , NetBeans , IntelliJ IDEA , y similares, viene con la integración incorporada de JUnit.
Para usar JUnit Test Framework en un proyecto Java, se debe agregar un archivo JUnit JAR en la ruta de clase del proyecto. Esto se requiere explícitamente si el IDE no está integrado con la biblioteca JUnit. El proceso es simple. Descargue el archivo JAR y agréguelo a la ruta de clases del proyecto.
Aquí hay algunos enlaces importantes al marco JUnit.
- Sitio oficial de JUnit
- API de Java JUnit
- Guía de usuario de JUnit
- Código fuente de JUnit en GitHub
A diferencia de JUnit 4 y sus predecesores, JUnit 5 trajo algunos cambios significativos. Además de muchas características nuevas agregadas, como compatibilidad con lambda, nuevas anotaciones e inyección de parámetros de métodos de prueba, la arquitectura central recibió algunas modificaciones significativas. JUnit 5 ahora es una arquitectura compuesta de tres módulos diferentes:JUnit Jupiter, JUnit Vintage y JUnit Platform. Los desarrolladores de casos de prueba, sin embargo, no necesitan preocuparse por las complejidades de los cambios. Los cambios significan principalmente un mejor soporte de herramientas, consistencia y API más limpias. Sobre todo, es totalmente compatible con versiones anteriores de JUnit 4. Por lo tanto, tampoco se preocupe. Consulte la guía del usuario de JUnit 5 para obtener más detalles.
Un ejemplo rápido
Aquí hay un ejemplo muy simple para echar un vistazo a cómo se pueden realizar las pruebas unitarias con el marco JUnit. Usamos el Empleado class para la prueba unitaria y cree una clase de prueba para dar una idea de su funcionamiento. El ejemplo es rudimentario hasta el punto de escribir un programa 'Hello World'. Los casos de prueba del mundo real, o incluso un ejemplo decente de prueba unitaria, requieren una buena cantidad de código. Tal vez lo intentemos en algún otro artículo.
package org.mano.unittest.examples; public class Employee { private final String name; private final double basicPay; public Employee(String name, double basicPay) { this.name=name; this.basicPay=basicPay; } public String getName() { return name; } public double getBasicPay() { return basicPay; } } package org.mano.unittest.examples; import org.junit.Test; import static org.junit.Assert.*; public class EmployeeTest { @Test public void constructorInitTest(){ Employee emp=new Employee("Odin", 2300); assertEquals("Odin", emp.getName()); assertEquals(2300, emp.getBasicPay(), 0.001); } } package org.mano.unittest.examples; public class EmployeeTestMain { public static void main(String[] args){ EmployeeTest et=new EmployeeTest(); et.constructorInitTest(); } }
Observe que la clase Empleado es inmutable con solo dos campos establecidos por el constructor. Debido a que solo vale la pena probar el método del constructor, solo probaremos eso.
La clase de prueba se llama EmployeeTest según la convención. La anotación @Test permite a JUnit designar un método como método de prueba. Hay una variedad de métodos de aserción en Assert clase. Aquí, hemos usado solo assertEquals .
Hay muchas formas de ejecutar una prueba escrita en JUnit. Normalmente, después de ejecutar los casos de prueba, imprime un resumen. Sin embargo, puede variar dependiendo de cómo se ejecute la prueba. Puede ejecutarse a través de IDE como Eclipse o IntelliJ, o herramientas como Maven, Gradle, etc. A veces, la única información que se recibe después de la prueba es que ha fallado o aprobado.
Conclusión
Hay varios otros marcos para pruebas unitarias. JUnit es un marco de prueba de unidad popular entre la comunidad Java. La prueba como una fase de ingeniería del sistema tiene mucho más proceso involucrado. Las pruebas unitarias son solo una parte de esto y, curiosamente, muchas de las pruebas de juego que realiza el desarrollador pueden denominarse pruebas unitarias. JUnit, como marco de prueba, le agrega valor. Las anotaciones y las API proporcionadas por JUnit automatizan muchas tareas y facilitan mucho la vida de los desarrolladores de pruebas unitarias.