By Gerald Mücke | May 29, 2015

Multi-Modul-Integrationstest-Abdeckung mit Jacoco und Sonar
In diesem Artikel beschreibe ich, wie man Jacoco für Maven-Multi-Modul-Projekte einrichtet, damit die Coverage von Integrationstests für die gesamte Codebasis berechnet und mit Sonarqube analysiert werden kann.
Gestern hatte ich Schwierigkeiten, die Integration-Test-Coveragesergebnisse in einem Multi-Modul-Projekt-Setup zu erfassen, was ich schließlich gelöst habe.
Nehmen wir also an, ich habe das folgende Setup:
rootModule
+Module1
+Module2
| +SubModule2-1
| +SubModule2-1-1
| +SubModule2-2
+ITModule
+ITModule1
Das ITModul enthält nur Integrationstests, wobei ITModul1 ein spezielles Szenario ist, das ein einzelnes Modul benötigt.
Modul2 besteht aus verschachtelten Untermodulen. Es gibt mehrere Beispiele, um einen Pfad wie ../target/jacoco-it.exec
zu verwenden, aber das funktioniert offensichtlich nicht, wenn man mehr als eine Verschachtelungsebene hat.
Um zu wissen, wie man es löst, muss man verstehen, wie Sonar die Analyse durchführt. Wenn Sonar die
Coverage-Informationen analysiert, prüft es den Code jedes Moduls gegen die in der
Eigenschaft sonar.jacoco.itReportPath
angegebene Coverage-Datei, die standardmäßig auf target/jacoco-it.exec
gesetzt ist. Also beim Analysieren von Modul1 prüft es nach Coverage-Informationen in Modul1/target/jacoco-it.exec
.
Da die Coverage-Daten aber im ITModul, bzw. ITModul1 erfasst werden, muss ich Sonar auf die Datei im ITModul
hinweisen.
Der beste Ort, um die Coverage-Daten zu sammeln, ist also das rootModule, d.h. rootModule/target/jacoco-it.exec
, und
daran werden die Ergebnisse aller IT-Tests angehängt.
Ich verwende die folgende Plugin-Konfiguration, die separate Dateien für die Coverage von Unit-Tests verwendet (den Append-Flag nicht vergessen, sonst wird die Gesamtcoverage falsch sein) und die zentrale Datei für die IT-Coverage.
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.4.201502262128</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>target/jacoco.exec</destFile>
<append>true</append>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>prepare-it-agent</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${session.executionRootDirectory}/target/jacoco-it.exec</destFile>
<append>true</append>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
</executions>
</plugin>
Das Property ${session.executionRootDirectory}
ist die Wurzel der Ausführung, wenn ich das gesamte Projekt baue, wird
es auf das rootModule verweisen. Dies ist also der beste Pfad, den man verwenden sollte, wenn man ein Multi-Modul mit
mehr als einer Ebene der Verschachtelung hat.
Für die Analyse muss ich Sonar anweisen, diese Datei zu verwenden, wenn die IT-Coverage analysiert wird. Daher muss ich
sonar.jacoco.itReportPath
auf diese Datei setzen. Leider funktioniert dies nicht mit
dem session.executionRootDirectory
-Property, und ich muss den absoluten Pfad zur Datei manuell einstellen. Ich
empfehle nicht, den absoluten Pfad in der pom.xml anzugeben, da dieser Pfad spezifisch für die Build-Umgebung ist.
Stellen Sie den Pfad also entweder in Sonar oder als Systemeigenschaft Ihrer Build-Umgebung ein. Ich habe es direkt in
den Sonar-Projekteinstellungen gesetzt (Java > Jacoco), zum Beispiel
/opt/buildroot/myProject/target/jacoco-it.exec
. Jetzt wird Sonar diese Datei für die IT-Coverage-Analyse jedes Moduls
überprüfen.