Cobertura en un proyecto maven multimódulo con JaCoCo

0
2655

En este tutorial vamos a explorar como tener la cobertura de nuestro código en un proyecto multimódulo usando Jacoco y maven. Iremos desde un único proyecto con un módulo a un proyecto multimódulo.

Índice de contenidos

1. Introducción

Tener la cobertura de un proyecto es una métrica más que podemos usar para ver que partes de nuestro código están cubiertas por tests. Según se puede ver a continuación, los microservicios están dejando de ser moda y puede que nos demos cuenta de que no siempre está bien usarlos.

Gartner Hype Cycle for Software Engineering 2022
Gartner Hype Cycle for Software Engineering 2022

Lo que aún no he visto es que los conceptos de encapsulación, modularidad y abstracción se dejen de usar. Con un monolito modular, en el black friday de 2021 Shopify alcanzó unos números espectaculares.

Hace mucho tiempo, Martin Fowler nos dijo que MonolithFirst, pero a lo mejor no le hicimos mucho caso.
En este tutorial vamos a intentar ver la evolución de un proyecto de un solo módulo, a separarlo en varios de manera que si algún día nos pasa y tenemos que crecer en distintos módulos sepamos como hacerlo y siempre tengamos métricas.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Lenovo t480 (1.80 GHz intel i7-8550U, 32GB DDR4).
  • Sistema Operativo: Sistema Operativo: Zorin OS 16.1
  • Entorno de desarrollo: IntelliJ IDEA 2022.2.2 (Ultimate Edition)
  • Apache Maven 3.8.6
  • Java version: 17.0.4, vendor: Eclipse Adoptium

3. ¿Que es la cobertura?

La cobertura del código es una métrica utilizada para ver las líneas de código que han sido cubiertas por los tests. Esta métrica también nos dice si se han cubierto todas las posibles bifurcaciones en el código, por lo que nos puede ayudar a detectar casos de prueba que no hemos implementado. La métrica tiene que ser interpretada como una métrica más, ya que puede ser que no tengamos los casos de prueba más adecuados. Para otro tipo de métricas como pueden ser los tests de mutación podemos verlos aquí, aquí o aquí. Robert C. Martin, en su libro Clean Code ya nos decía que cuanta más cobertura tuviéramos, menos miedo.

The higher your test coverage, the less your fear.

Robert C. Martin, Clean Code (2009), 124.

4. JaCoCo en un único proyecto

Vamos a empezar desde lo más básico hasta conseguir la cobertura en un proyecto multimódulo. El ejemplo va a ser una calculadora básica donde veremos como tener cobertura.

4.1. La aplicación

Nuestro ejemplo va a ser una calculadora muy sencilla, donde la clase calculadora es:

Calculator.java

Tenemos nuestros tests:

CalculatorTest.java

Y el proyecto configurado de la siguiente manera:

pom.xml

Si ejecutamos:

Tenemos:

Bien, 4 tests ejecutados, sin fallos ni nada, pero ¿Cómo sabemos que estamos cubriendo todo el código? Ahora vemos como añadirle cobertura.

4.2. Cambios en el pom.xml

Añadir JaCoCo es tan sencillo como añadirlo al pom.xml de esta forma:

pom.xml

Estamos diciéndole al plug-in que en la fase de test nos haga los informes. Con esto ya lo tendríamos, el pom.xml entero se quedaría así:

pom.xml

Ahora si ejecutamos

Vemos la sutil diferencia que el plug-in de JaCoCo que hemos añadido se ha ejecutado y nos ha generado un informe. Este informe está en la carpeta target/site/index.html y se ve así:

Primer ejemplo de informe de JaCoCo
Primer ejemplo de informe de JaCoCo

5. JaCoCo multimódulo

Ahora que ya hemos visto como tener la cobertura en un único módulo, vamos al siguiente nivel, vamos a ver como tener la cobertura en varios módulos. Vamos a imaginar que la calculadora es un éxito tan grande que vamos a partirlo en módulos, uno que hace sumas y restas y otro que hace multiplicaciones y divisiones. Esto nos permitirá el día de mañana poder hacer despliegues separados, tener equipos trabajando en módulos distintos sin que se molesten demasiado etc.

5.1. Cambios en la aplicación

Primero vamos a tener dos módulos, uno para las sumas y las restas, otro para las multiplicaciones y divisiones. El código es el mismo pero separado. El pom.xml de la aplicación que contiene los módulos quedaría así:

pom.xml

Vemos que se le ha quitado la parte que generaba los informes porque no es relevante tener los HTML por módulo ya que se van a agregar, lo que importa es que JaCoCo se lance y deje los resultados.

El módulo de las sumas y restas quedaría así:

pom.xml

AdditionAndSubtraction.java

Los tests:

AdditionAndSubtractionTest.java

El módulo de las multiplicaciones y divisiones quedaría así:

pom.xml

MultiplicationAndDivision.java

Los tests:

MultiplicationAndDivisionTest.java

Ahora si ejecutamos

Todo ha ido correcto, hemos podido ver que se construyen todos los módulos y pasan los tests. Pero … ¿Donde están los informes?

5.2. Que ha pasado con la cobertura

Ahora que tenemos distintos módulos, no tenemos un único informe, tenemos uno por módulo (aunque quitamos del plug-in su generación en HTML). Esto es algo que no suele ser lo deseado, ya que no es viable ir recorriendo todos los módulos viendo que tal esta cada uno, queremos un único sitio donde podamos ver el estado de la aplicación. Esto lo conseguiremos haciendo un módulo que agregue todos los informes de los módulos en uno solo. Desde la versión 0.7.7 de JaCoCo esto es posible, ya que nos ofrece el goal report-aggregate. De hecho como habéis visto lo anterior era la parte fácil del tutorial y esta será la interesante, pero siempre está bien ponernos en situación.

5.3. Nuevo módulo de agregación

Este nuevo módulo se llamará jacoco-report-aggregate. El módulo tiene que:

  • Tener el plug-in de JaCoCo con el goal report-aggregate.
  • Tener los módulos de los que queremos agregar los informes como dependencias.
  • Poner la propiedad maven.deploy.skip a true (o a releases, snapshots o false según sea conveniente).
  • Dejar el packaging a jar aunque se vea un warning como este: [WARNING] JAR will be empty – no content was marked for inclusion!. Si no se deja así no generara el informe.

El nuevo modulo tiene el siguiente pom.xml:

pom.xml

Ahora si ejecutamos

Vemos que el módulo de agregación va a por los resultados de los otros módulos, los agrega y dentro de su carpeta target/site/index.html lo tenemos todo agregado.

Primer ejemplo de informe de JaCoCo agregado
Primer ejemplo de informe de JaCoCo agregado

5.4. Los tests de integración

Si tenemos tests de integración la cosa se complica un poco. Imaginemos un nuevo módulo Calculator que hace uso de los otros servicios para hacer una operación sumAndMultiply y hacemos un test de integración para ver que todo es correcto. Añadimos el nuevo módulo y cambiamos a verify la agregación. También añadimos el plug-in de failsafe para poder ejecutar los tests en el pom principal. Con esto ya quedaría configurado.

pom.xml

En el módulo que agrega:

pom.xml

La nueva clase

Calculator.java

Su test de integración

CalculatorIT.java

Ahora si ejecutamos

Ejemplo de informe de JaCoCo agregado con test de integración
Ejemplo de informe de JaCoCo agregado con test de integración

Aquí hay que tener en cuenta varias cosas. La primera seria ver que al poner los tests de integración se están ejecutando, es decir, tenemos el plugin de failsafe bien configurado. Luego, tenemos que ver que el agente de jacoco está bien configurado.

Si tenemos alguna configuración que no es compatible, puede darse el caso de que no se esté ejecutando bien JaCoCo. Para solucionar esto tenemos que configurar JaCoCo y failsafe. Al plug-in de JaCoCo le tenemos que decir que prepare el agente en la fase de integración con el parámetro propertyName que puede ser cualquier cosa, pero tiene que estar igual en argLine de failsafe

pom.xml configuración extra de JaCoC0

pom.xml configuración extra de failsafe

6. Conclusiones

Hemos hecho un breve repaso por como obtener la cobertura de nuestro código. Es importante tener algún tipo de métrica (o varias) que nos digan que partes del código están cubiertas por test e idealmente si esa cobertura es buena o mala. Hemos empezado en un proyecto con un solo módulo que hemos ido partiendo en distintos módulos y hemos visto como agregar los informes en un solo sitio para que de un golpe de vista podamos ver el estado del proyecto. También hemos incluido tests de integración que son un poco más especiales.

7. Referencias

Dejar respuesta

Please enter your comment!
Please enter your name here