Los tests son una parte fundamental del código, nos ayudan a asegurar la calidad del mismo, aseguran que cualquier refactor que se vaya hacer no modifica el correcto funcionamiento de la aplicación e incluso puede ser util para entender el flujo de la aplicación y los casos de uso que se están manejando.
Sin embargo, como desarrollador, puede ser difícil hacer seguimiento de los tests que estás probando, más aún si no sigues lineamientos como TDD que te incitan a testear mientras desarrollas, mas no al final. Esto pasa especialmente con aplicaciones escalables o muy grandes, en las cuales el código es demasiado grande o cambiante como para considerar todos los escenarios posibles. En vista de esto, nace un factor importante a la hora de testear tus aplicaciones: la cobertura o coverage, el coverage te ayuda a saber qué porcentaje de tu código has probado satisfactoriamente (esto medido en la cantidad de escenarios, de clases y hasta de líneas de código que se han probado vs las que no).
Pero, hacer este seguimiento de manera manual es humanamente imposible, especialmente cuando la aplicación en la cual se trabaja sigue creciendo y creciendo. Es por ello que se creó la herramienta que introduciremos hoy: JaCoCo. JaCoCo es una herramienta que analiza la cobertura en pruebas que se tienen y te genera un reporte en formato HTML en una manera similar a como funciona Javadoc, en el presente Tutorial explicaremos cómo integrar JaCoCo a un proyecto hecho con Java utilizando Maven. Recordemos que para efectos de este tutorial, partimos de la idea de que ya existen las clases funcionales y los tests.
Consideremos que tenemos el siguiente código fuente:
public class HelloWorld {
publicstaticString greeting(String name) throws IllegalArgumentException{
if(name.trim().isEmpty()) thrownew IllegalArgumentException("Name cannot be empty");
return"Hello World!, I'm "+name;
}
publicstaticvoid main(String[] args) {
System.out.println(greeting("Juan Pablo"));
}
}
Y consideremos también que tenemos el siguiente test unitario de la clase anterior:
import org.junit.*;import static org.junit.Assert.*;import static org.hamcrest.CoreMatchers.*;publicclassHelloWorldTest{
@Test
publicvoid testGreet() {
assertThat(HelloWorld.greeting("Bart Simpson"), is("Hello World!, I'm Bart Simpson"));
}
}
Inicialmente, expliquemos el código anterior: tenemos dos métodos estáticos, uno que retorna el String de un saludo en base al nombre que recibe por parámetro, y adicionalmente el método main que invoca al método greet para imprimir un saludo. Adicionalmente, observemos que el test prueba tan solo un escenario, el caso en el cual se envía un parámetro correcto y se espera un saludo bien formado, JaCoCo en este caso nos ayudaría a identificar esos escenarios que olvidamos probar. Ahora, una vez explicado nuestro ejemplo y partiendo de la idea de que ya tenemos el código y las pruebas unitarias de ese código, es necesario incluir JaCoCo en el archivo pom.xml
<plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.2</version><executions><execution><goals><goal>prepare-agent</goal></goals></execution><execution><id>report</id><phase>test</phase><goals><goal>report</goal></goals></execution></executions></plugin>
Posteriormente, teniendo todo listo y funcional, procedamos a ejecutar los Tests con el comando:
mvn test
Esto nos debería arrojar el siguiente resultado o algo similar:
Podemos observar que maven nos informa que guardo un archivho llamado jacoco.exec, este sirve para cargar la información generada por JaCoCo a otras herramientas de visualización como puede ser SonarQube. Sin embargo, como nosotros queremos visualizar de una manera más directa única y exclusivamente la cobertura de las pruebas, podemos usar un HTML simple que genera JaCoCo y lo ubica igualmente en el archivo:
target/site/jacoco/index.html
Ahora, si abrimos el archivo index.html en un explorador como Chrome, podemos navegar a lo largo de las carpetas y archivos de nuestro proyecto, evidenciando en cada paso la cobertura que tiene cada paquete y, si entramos en una clase en particular, podremos observar exactamente qué líneas de código, escenarios y rutas faltaron por probar:
Como podemos ver en este aso, en la primera imagen observamos que el 50% del código está cubierto por pruebas (idealmente, en un proyecto de mayor tamaño se busca una cobertura cercana al 80%), adicionalmente podemos ver en la segunda imagen los métodos que podemos probar y la cobertura de los mismos, finalmente si entramos a la clase HelloWorld, observamos que en color verde aparece la línea del caso de éxito que probamos pero aparece en color amarillo o de advertencia, que si bien se accedió al if, no se hizo la prueba con el escenario que arroja la excepción.
Como conclusión, podemos decir que JaCoCo es una herramienta de fácil integración tanto con un proyecto que apenas está iniciando como con uno que ya lleve bastante código dentro de sí. Dada su fácil integración y uso, JaCoCo no es nada intrusivo y puede ser agregado a cualquier proyecto Java que ya tenga una estructura de pruebas definidas. Adicionalmente, vemos que esta herramienta puede ser sumamente útil para mejorar la calidad de nuestras pruebas y nos ayudan a asegurar que efectivamente estamos considerando todas las rutas y escenarios posibles en nuestra aplicación.
Pregunta: cual es la version de Junit que se uso para el ejemplo?