Exclusiones en Jacoco con Maven
En esta entrada vamos a ver como podemos realizar exclusiones en Jacoco con Maven, sobre packages y clases para los informes de cobertura.
Por lo general, se suele excluir código autogenerado (por ejemplo si usas algún plugin de generación de código de OpenAPI) y DTOs u objetos de dominio o mappers. Siempre y cuando no tengamos lógica en estas clases.
¿Qué es Jacoco?
Jacoco es la contracción de las palabras Java Code Coverage, el cual es un proyecto de código abierto el cual es utilizado para verificar la cobertura de nuestro código.
Jacoco puede integrar informes y se integra con diferentes IDEs además se puede integrar con plugins de Jenkins o con SonarQube parar verificar el código en una pipeline desde fuera de nuestro entorno de desarrollo.
Exclusiones en Jacaco desde Maven
Vamos a aplicar los informes de Jacoco al siguiente proyecto:
Vamos a comenzar viendo como podemos realizar exclusiones haciendo uso de un plugin en Maven.
Para excluir podemos hacer uso de * y de ?:
- * identifica de cero a n caracters
- ** identifica de cero a n directorios.
- ? representa un único caracter.
Lo primero que necesitamos para realizar exclusiones en Maven es añadir el plugin de Jacoco:
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>${jacoco.version}</version> </plugin>
Hay que tener en cuenta que si hacemos uso de JUnit 5 además tendremos que añadir el plugin de surefire:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> <!--..... configuración adicional--> </plugin>
Si ejecutamos Jacoco sin ninguna exclusión y vamos a la carpeta target/site/jacoco/index.html veremos lo siguiente:
Y dentro de entity tenemos las siguientes clases:
Una vez hemos añadido el plugin de Jacoco es el momento de realizar su configuración para realizar exclusiones, por ejemplo, vamos a excluir los típicos paquetes de config.
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>${jacoco.version}</version> <configuration> <excludes> <exclude>**/config/*</exclude> </excludes> </configuration> </plugin>
Al ir a target/site/jacoco/index.html vemos que se han aplicado las exclusiones.
O a excluir las entity Department de nuestra aplicación:
<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>${jacoco.version}</version> <configuration> <excludes> <exclude>com/refactorizando/**/Department.class</exclude> </excludes> </configuration> </plugin>
Exclusión código generado por Lombok
Lo más habitual cuando trabajamos con proyectos con Maven y con Spring es hacer uso de Lombok. Lombok nos ayuda a simplificar nuestro código y a eliminar el boilerplate de Java.
El código autogenerado por Lombok podemos evitar que aparezca en los informes de Jacoco mediante una exclusión a través de un fichero.
El fichero que tenemos que añadir en la raíz del proyecto se tiene que llamar lombok.config:
lombok.addLombokGeneratedAnnotation = true
Este fichero se encarga de añadir la anotación @Generated a los métodos, classes y campos para todo lo relacionado con Lombok, lo que hace evitar que Jacoco lo analice.
En el siguiente punto veremos el uso de la anotación @Generated para evitar que Jacoco analice código cuando se hace uso de la anotación @Generated.
Excluir código para analizar por Jacoco con anotación
Una de las funcionalidades de Jacoco es poder excluir clases y métodos con una anotación que customizada. Para crear una anotación para Jacoco que nos permita exclusiones tiene que cumplir que la anotación incluya en su nombre Generated y que se cree en runtime.
Vamos a crear una anotación
@Documented @Retention(RUNTIME) @Target({TYPE, METHOD, CONSTRUCTOR}) public @interface JacocoAnnotationGenerated { }
Una vez que tenemos creada nuestra anotación podemos aplicarlo a métodos, constructores y clases.
Por ejemplo si lo aplicamos a la clase de la entidad Employee:
@Getter @Setter @Entity @JacocoAnnotationGenerated public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String name; @ManyToOne private Department department; }
Omitimos la clase Employee de la ejecución de Jacoco.
Hay que tener en cuenta que la anotación anterior se puede aplicar a métodos, constructores y clases.
Conclusión exclusiones en Jacoco con Maven
Poder aplicar exclusiones en Jacoco con Maven es de vital importancia cuando tenemos código autogenerado o clases de configuración que no necesitamos analizar su cobertura. Jacoco a través de su plugin en maven o de su anotación en Java nos facilita las exclusiones de una manera fácil y sencilla.
Si quieres ver el ejemplo que hemos utilizado puedes hacerlo aquí.
Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!