Code Coverage des Nuclos Builds und Integrationstests-Laufs wird mit folgenden Schritten erreicht. (ab v4.2024.13)

  1. JaCoCo Weaving Aufruf (jacoco-maven-plugin) nach JavaC aber bevor AspectJ den Bytecode noch weiter manipuliert. Die so genannte Offline Variante.
  2. Einbindung der JaCoCo Runtime als Dependency in allen Maven Modulen.
  3. Ausführung der Unit-Tests wie auch Integrationstests mit der Anweisung alle Coverage Daten in ein File zu schreiben: NUCLOS_GIT_ROOT/target/jacoco.exec
  4. JaCoCo Report Erstellung für alle angeforderten Maven Module mittels eines gesonderten Maven Aufrufs: mvn jacoco:report@coverage-report
  5. (Sonar Code Analyse verwendet automatisch die von JaCoCo generierten Reports, wenn vorhanden)

Details zum Ablauf

zu 1-3.) Build und Testausführung

Auch wenn das Weaving zur Laufzeit (Online) die offiziell empfohlene Variante ist, so hatten wir bei Nuclos damit keinen Erfolg. Ein Grund dafür dürfte AspectJ sein und möglicherweise auch Spring Weaving.
Zur Aktivierung muss nur das Maven Profil coverage verwendet werden. Hier ein Beispiel Aufruf zum Bau und zur Ausführung der Tomcat-Serverintegrationstests samt JaCoCo Datensammlung:

mvn clean verify -Dlocale=de_DE -Dtest.webclient.skip=true -P coverage,test,test-tomcat

Die von JaCoCo gesammelten Daten aller Tests findet man im Anschluss unter NUCLOS_GIT_ROOT/target/jacoco.exec

Nur zu Testzwecken

Solche Nuclos Builds sind nur für Testzwecke, nicht für den produktiven Einsatz geeignet.

zu 4.) JaCoCo Report

Da das Integrationstest-Mavenmodul den Löwenanteil der Coverage für die anderen Module sammelt, können die JaCoCo Reports für die einzelnen Module erst nach dem Testlauf, unter Verwendung der NUCLOS_GIT_ROOT/target/jacoco.exec, erzeugt werden.
Ein gesonderter Maven Aufruf ist hierfür nötig:

mvn jacoco:report@coverage-report

Im Anschluss sind die JaCoCo Reports zu finden unter MAVEN_MODUL/target/site/jacoco der unterschiedlichen Maven Module.

zu 5.) Sonar Analyse unter Verwendung der JaCoCo Reports

Die Einstellungen bezüglich Sonar in der Nuclos Maven pom.xml schalten die Coverage Auswertung zur Code Analyse automatisch hinzu:

mvn sonar:sonar

Die Sonar Analyse ist im Anschluss in der Cloud zu finden unter: https://sonarcloud.io/project/overview?id=nuclos_nuclos

(Ein Hochladen setzt natürlich eine Berechtigung voraus die mit einer Umgebungsvariable SONAR_TOKEN gesetzt werden muss)

Wichtig: Das Sonar Maven Plugin benötigt Java 17

Knowledge Transfer

Es waren viele Anläufe nötig, um die Coverage eines Nuclos Integrationstest-Laufs sammeln zu können. Die wichtigsten Fehlschläge und Erfahrungen im Umgang mit den Frameworks sollen hier festgehalten werden, und ermöglichen in Zukunft hoffentlich eine Reduzierung der Komplexität, mit der wir jedoch gezwungen waren zu starten.

--- Stand Juni 2024 ---

Ohne Zweifel wäre ein Weaving zur Laufzeit simpler in der Verwendung, damit ging es also schon los. Die Offline Variante muss direkt nach dem maven-compiler-plugin erfolgen und noch bevor das aspectj-maven-plugin seine Arbeit verrichtet (Execution ID instrument-for-coverage-before-aspectj), da ansonsten auch nichts aufgezeichnet wird.

Die Reports von JaCoCo benötigen bei einer Offline Verwendung zwingend die originalen Klassen, wie es hier beschrieben wird: https://www.eclemma.org/jacoco/trunk/doc/classids.html
Die originalen Klassen sollten eigentlich mit dem goal jacoco:restore-instrumented-classes (https://www.eclemma.org/jacoco/trunk/doc/restore-instrumented-classes-mojo.html) wiederhergestellt werden können, hinterlässt aber in unseren Fall Spuren des Weavings, was bei der Report Erzeugung zu Fehlern führt.
Als Workaround kompilieren wir nach den Tests einfach ein weiteres mal. Die Executions hierfür tragen die IDs clean-instrumented-classes und restore-javac-only-classes. Leider verursacht dieser Workaround einen Fehler im war Archiv, anstatt nuclos-*.jar(s) unter WEB-INF/lib werden nur leere Verzeichnisse angelegt. Ursache bisher noch unbekannt, die Jars stehen weiterhin nach dem manuellen Clean+Restore im target der einzelnen Module zur Verfügung. Also ist ein Workaround für den Workaround nötig, zu finden unter der execution ID force-jar-delivery-to-war. Diese sorgt dafür, dass nach der Erzeugung der einzelnen Jars diese nach NUCLOS_GIT_ROOT/nuclos-war/target-force kopiert werden. Alles was sich hier befindet, wird beim packen des war vorrangig verwendet und verhindert/überschreibt die leeren Verzeichnisse.

Für die JaCoCo Report Erzeugung steht bei einem Multi Maven Modul Projekt eigentlich das Goal jacoco:report-aggregate zur Verfügung, wie hier vorgeschlagen: https://community.sonarsource.com/t/coverage-test-data-importing-jacoco-coverage-report-in-xml-format/12151
Womit ein Report zur Gesamtübersicht erzeugt werden sollte, was in unseren Versuchen leider nicht zu den gewünschten Ergebnis geführt hat. Hierfür wurde testweise ein "it-report" Maven Modul angelegt und als letztes, nach den Integrationstest, verarbeitet. Eine mögliche Ursache könnte die Offline Variante sein. Ein Report pro Modul ist für Sonar aber vollkommen ausreichend und soll uns auch genügen, hätte aber den einzelnen Maven Aufruf (4.) eingespart.

Die hier beschriebenen Executions treten nur in Kraft, wenn das Profile coverage aktiviert wird.

Es ist nicht auszuschließen, dass einige Phänomene durch eine IDE (in unserem Fall IntelliJ) erzeugt werden, da wir hier immer wieder über merkwürdige Unterschiede stolpern im Umgang mit Maven. Ein Maven Befehl, abgesetzt über eine IntelliJ Maven Run Configuration erzeugt unter ungünstigen Umständen immer wieder einen Fehler. Wobei der vermeintlich gleiche Befehl (1-3. siehe weiter oben) über Bash ohne Probleme durchläuft. 


  • Keine Stichwörter