Introducción a JaCoCo

1. Información general

La cobertura de código es una métrica de software que se utiliza para medir cuántas líneas de nuestro código se ejecutan durante las pruebas automatizadas.

En este artículo, analizaremos algunos aspectos prácticos del uso de JaCoCo , un generador de informes de cobertura de código para proyectos Java.

2. Configuración de Maven

Para empezar a trabajar con JaCoCo, necesitamos declarar este complemento de Maven en nuestro archivo pom.xml :

 org.jacoco jacoco-maven-plugin 0.7.7.201606060606    prepare-agent    report prepare-package  report     

El enlace proporcionado aquí antes siempre lo llevará a la última versión del complemento en el repositorio central de maven.

3. Informes de cobertura de código

Antes de comenzar a ver las capacidades de cobertura de código de JaCoCo, necesitamos tener una muestra de código. Aquí hay una función de Java simple que verifica si una cadena lee lo mismo hacia atrás y hacia adelante:

public boolean isPalindrome(String inputString) { if (inputString.length() == 0) { return true; } else { char firstChar = inputString.charAt(0); char lastChar = inputString.charAt(inputString.length() - 1); String mid = inputString.substring(1, inputString.length() - 1); return (firstChar == lastChar) && isPalindrome(mid); } }

Todo lo que necesitamos ahora es una simple prueba de JUnit :

@Test public void whenEmptyString_thenAccept() { Palindrome palindromeTester = new Palindrome(); assertTrue(palindromeTester.isPalindrome("")); }

La ejecución de la prueba con JUnit pondrá en movimiento automáticamente el agente JaCoCo, por lo que creará un informe de cobertura en formato binario en el directorio de destino : target / jacoco.exec.

Obviamente, no podemos interpretar el resultado con una sola mano, pero otras herramientas y complementos pueden hacerlo, por ejemplo, Sonar Qube .

La buena noticia es que podemos utilizar el objetivo jacoco: report para generar informes de cobertura de código legibles en varios formatos, por ejemplo, HTML, CSV y XML.

Ahora podemos echar un vistazo, por ejemplo, a la página target / site / jacoco / index.html para ver cómo se ve el informe generado:

Siguiendo el enlace proporcionado en el informe - Palindrome.java , podemos navegar a través de una vista más detallada para cada clase de Java:

Tenga en cuenta que puede administrar directamente la cobertura del código utilizando JaCoCo dentro de Eclipse sin configuración , gracias al complemento EclEmma Eclipse.

4. Análisis de informes

Nuestro informe muestra una cobertura de instrucciones del 21%, cobertura de ramas del 17%, 3/5 para la complejidad ciclomática, etc.

Las 38 instrucciones mostradas por JaCoCo en el informe se refieren a las instrucciones de código de bytes en contraposición a las instrucciones de código Java ordinarias.

Los informes de JaCoCo le ayudan a analizar visualmente la cobertura del código mediante el uso de diamantes con colores para las ramas y colores de fondo para las líneas:

  • El diamante rojo significa que no se han ejercitado ramas durante la fase de prueba.
  • El diamante amarillo muestra que el código está parcialmente cubierto; algunas sucursales no se han ejercido.
  • El diamante verde significa que todas las ramas se han ejercitado durante la prueba.

El mismo código de color se aplica al color de fondo, pero para la cobertura de líneas.

JaCoCo proporciona principalmente tres métricas importantes:

  • La cobertura de líneas refleja la cantidad de código que se ha ejercido en función del número de instrucciones de código de bytes de Java llamadas por las pruebas.
  • La cobertura de sucursales muestra el porcentaje de sucursales ejercidas en el código, generalmente relacionado con declaraciones if / else y switch .
  • La complejidad ciclomática refleja la complejidad del código al proporcionar el número de rutas necesarias para cubrir todas las rutas posibles en un código mediante una combinación lineal.

Para tomar un ejemplo trivial, si no hay declaraciones if o switch en el código, la complejidad ciclomática será 1, ya que solo necesitamos una ruta de ejecución para cubrir todo el código.

Generalmente, la complejidad ciclomática refleja el número de casos de prueba que necesitamos implementar para cubrir todo el código.

5. Desglose de conceptos

JaCoCo se ejecuta como un agente de Java , es responsable de instrumentar el código de bytes mientras se ejecutan las pruebas. JaCoCo profundiza en cada instrucción y muestra qué líneas se ejercitan durante cada prueba.

Para recopilar datos de cobertura, JaCoCo utiliza ASM para la instrumentación de código sobre la marcha, recibiendo eventos de la interfaz de la herramienta JVM en el proceso:

También es posible ejecutar el agente JaCoCo en modo servidor, en este caso, podemos ejecutar nuestras pruebas con jacoco: dump como objetivo, para iniciar una solicitud de volcado.

Puede seguir el enlace de la documentación oficial para obtener más detalles sobre el diseño de JaCoCo.

6. Puntaje de cobertura de código

Ahora que sabemos un poco sobre cómo funciona JaCoCo, mejoremos nuestra puntuación de cobertura de código.

Para lograr una cobertura de código del 100%, necesitamos introducir pruebas que cubran las partes faltantes que se muestran en el informe inicial:

@Test public void whenPalindrom_thenAccept() { Palindrome palindromeTester = new Palindrome(); assertTrue(palindromeTester.isPalindrome("noon")); } @Test public void whenNearPalindrom_thanReject(){ Palindrome palindromeTester = new Palindrome(); assertFalse(palindromeTester.isPalindrome("neon")); }

Now we can say that we have enough tests to cover our the entire code, but to make sure of that, let's run the Maven command mvn jacoco:report to publish the coverage report:

As you can see all lines/branches/paths in our code are fully covered:

In real world project, and as developments go further, we need to keep in track the code coverage score.

JaCoCo offers a simple way of declaring minimum requirements that should be met, otherwise the build will fail.

We can do that by adding the following check goal in our pom.xml file:

 jacoco-check  check     PACKAGE   LINE COVEREDRATIO 0.50      

As you can probably guess, we're limiting here the minimum score for lines coverage to 50%.

The jacoco:check goal is bound to verify, so we can run the Maven command – mvn clean verify to check whether the rules are respected or not. The logs will show something like:

[ERROR] Failed to execute goal org.jacoco:jacoco-maven-plugin:0.7.7.201606060606:check (jacoco-check) on project mutation-testing: Coverage checks have not been met.

7. Conclusion

In this article we've seen how to make use of JaCoCo maven plugin to generate code coverage reports for Java projects.

Keep in mind though, 100% code coverage does not necessary reflects effective testing, as it only reflects the amount of code exercised during tests. In a previous article, we've talked about mutation testing as a more sophisticated way to track tests effectiveness compared to ordinary code coverage.

Puede consultar el ejemplo proporcionado en este artículo en el proyecto de GitHub vinculado .