Couverture de code multi-module avec Jacoco et Sonar

J’ai récemment été confronté à un problème à priori courant, mais sur lequel j’ai trouvé peu de documentation. Je vous partage donc le résultat de mes expérimentations, en espérant vous faire économiser quelques heures de recherches.

Le code source est présent ici. Chaque commit montre une étape de résolution du problème

Il faut noter que cet article ne parle pas de la pertinence ou non de faire du coverage, mais simplement de s’assurer que, si cette métrique est utilisée, elle le soit correctement.

Le problème

Je travaille sur un projet Maven composé de plusieurs modules (ici uniquement 2 pour simplifier), et certains dépendent des autres. Voilà une représentation simpliste du projet :

-module A
  - pom.xml
- module B (dépend de A)
  - pom.xml
- pom.xml

État initial du projet

J’ai principalement 2 types des tests :

  • des TU dans le module A
  • des tests “de bout en bout” dans le module B

La situation est la suivante :

  • les tests du module B passent sur du code du module A (car B dépend de A)
  • les TU ne couvrent pas tout le code du module A (car les tests de B passent déjà dessus).

Par défaut, Jacoco ne sait pas calculer une couverture de tests sur un module externe. En d’autres termes, les tests exécutés sur B ne prendront pas en compte la couverture effectuée sur A (je n’ai pas creusé le pourquoi en détail, mais je suppose que le coverage est écrasé entre chaque test de module).

Une fois Jacoco configuré (voir ici), on remarque que le coverage n’est pas de 100%.

Screenshot-2019-01-02-at-17.05.16

En détails :

Screenshot-2019-01-02-at-17.06.24

Encore plus en détails :

Screenshot-2019-01-02-at-17.07.12

La solution

La solution à ce problème est assez simple, et tient en 2 parties à effectuer dans le pom.xml racine :

  • configurer le plugin Jacoco pour merger le coverage de chaque module dans un fichier global (à la racine du module par exemple),
  • indiquer à Sonar d’utiliser ce fichier compilé plutôt que les fichiers de modules.
     <build>
         <plugins>
             <plugin>
                 <groupId>org.jacoco</groupId>
                 <artifactId>jacoco-maven-plugin</artifactId>
                 <version>0.8.2</version>
                 <executions>
                 [...]
                    <execution>
	                        <id>merge</id>
	                        <goals>
	                            <goal>merge</goal>
	                        </goals>
	                        <configuration>
	                            <fileSets>
	                                <fileSet implementation="org.apache.maven.shared.model.fileset.FileSet">
	                                    <directory>${project.basedir}</directory>
	                                    <includes>
	                                        <include>**/*.exec</include>
	                                    </includes>
	                                </fileSet>
	                            </fileSets>
	                        </configuration>
	                    </execution>
                 [...]
  <properties>
	[...]
	<!-- Tell sonar where to look for the coverage file. Property inherited by submodules -->  
     					 		<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
	</properties>

Ces modifications sont visibles ici.

Une fois effectuées, voilà le résultat dans Sonar :

Screenshot-2019-01-02-at-17.11.24

Conclusion

Le problème est résolu en quelques lignes de configuration… mais encore faut-il le savoir.

Pour aller plus loin, Jacoco est capable de fournir un rapport de coverage “hors de Sonar”, mais je n’ai pas réussi à le faire fonctionner correctement. J’accepte les pull-requests si vous en avez le courage, sinon je ferai un nouvel article le jour où j’en aurai besoin !


Vous avez trouvé cette publication utile? Cliquer sur
Ippon
Ippon est un cabinet de conseil en technologies, créé en 2002 par un sportif de Haut Niveau et un polytechnicien, avec pour ambition de devenir leader sur les solutions Digitales, Cloud et BigData.

Ippon accompagne les entreprises dans le développement et la transformation de leur système d’information avec des applications performantes et des solutions robustes.

Ippon propose une offre de services à 360° pour répondre à l’ensemble des besoins en innovation technologique : Conseil, Design, Développement, Hébergement et Formation.

Nous avons réalisé, en 2017, un chiffre d’affaires de 31 M€ en croissance organique de 30%. Nous sommes aujourd’hui un groupe international riche de plus de 320 consultants répartis en France, aux USA, en Australie et au Maroc.
FRANCE Website LinkedIn