Ich war in der gleichen Situation wie Sie. Die im Internet verstreuten halben Antworten waren ziemlich ärgerlich, da es den Anschein hatte, dass viele Menschen das gleiche Problem hatten, aber niemand konnte sich die Mühe machen, vollständig zu erklären, wie sie es gelöst haben.
Die Sonar-Dokumente beziehen sich auf ein GitHub-Projekt mit hilfreichen Beispielen . Um dies zu lösen, habe ich die Logik der Integrationstests auf reguläre Komponententests angewendet (obwohl ordnungsgemäße Komponententests submodulspezifisch sein sollten, ist dies nicht immer der Fall).
Fügen Sie in der übergeordneten Datei pom.xml die folgenden Eigenschaften hinzu:
<properties>
<!-- Sonar -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
</properties>
Dadurch kann Sonar Unit-Testberichte für alle Submodule an derselben Stelle abrufen (ein Zielordner im übergeordneten Projekt). Außerdem wird Sonar angewiesen, manuell ausgeführte Berichte wiederzuverwenden, anstatt eigene Berichte zu erstellen. Wir müssen nur das Jacoco-Maven-Plugin für alle Submodule laufen lassen, indem wir dies im übergeordneten POM in Build / Plugins platzieren:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.6.0.201210061924</version>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<executions>
<execution>
<id>agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
destFile
Platziert die Berichtsdatei an der Stelle, an der Sonar danach sucht, und append
lässt sie an die Datei anhängen, anstatt sie zu überschreiben. Dadurch werden alle JaCoCo-Berichte für alle Submodule in derselben Datei kombiniert.
Sonar wird diese Datei für jedes Submodul untersuchen, da wir ihn oben darauf hingewiesen haben, was uns kombinierte Unit-Testergebnisse für Multi-Modul-Dateien in Sonar liefert.
mvn package
vor dem Ausführenmvn sonar:sonar
eine neue erstellen, um den neuen Berichtspfad zu generieren.FAQ
Fragen aus dem Kopf seitdem bin ich verrückt nach Jacoco geworden.
Mein Anwendungsserver (jBoss, Glassfish ..) befindet sich im Irak, Syrien, was auch immer. Ist es möglich, eine Abdeckung mit mehreren Modulen zu erhalten, wenn Integrationstests darauf ausgeführt werden? Jenkins und Sonar befinden sich ebenfalls auf verschiedenen Servern.
Ja. Sie müssen jacoco agent verwenden , der im Modus
output=tcpserver
jacoco ant lib ausgeführt wird. Grundsätzlich zweijar
s. Dies gibt Ihnen 99% Erfolg.Wie funktioniert Jacoco Agent?
Sie fügen eine Zeichenfolge hinzu
auf Ihren Anwendungsserver JAVA_OPTS und starten Sie ihn neu. In dieser Zeichenfolge muss nur
[your_path]
der Pfad zu jacocoagent.jar ersetzt werden, der auf Ihrer VM gespeichert (gespeichert!) Ist, auf der der App-Server ausgeführt wird. Seit dem Start des App-Servers werden alle bereitgestellten Anwendungen dynamisch überwacht und ihre Aktivität (dh die Verwendung von Code) kann von Ihnen per tcl-Anforderung im jacocos .exec-Format abgerufen werden.Könnte ich den jacoco-Agenten zurücksetzen, um erst seit Beginn meines Tests mit der Erfassung von Ausführungsdaten zu beginnen?
Ja, zu diesem Zweck benötigen Sie das Build-Skript jacocoant.jar und ant in Ihrem Jenkins-Arbeitsbereich.
Was ich also von http://www.eclemma.org/jacoco/ benötige, ist jacocoant.jar in meinem Jenkins-Arbeitsbereich und jacocoagent.jar auf meiner App-Server-VM?
Das stimmt.
Ich möchte keine Ameise verwenden, ich habe gehört, dass das Jacoco Maven Plugin all diese Dinge auch kann.
Das ist nicht richtig, das jacoco maven Plugin kann Unit-Testdaten und einige Integrationstestdaten sammeln (siehe Arquillian Jacoco ), aber wenn Sie zum Beispiel Tests als separate Build-in-Jenkins versichern und die Abdeckung mehrerer Module zeigen möchten, kann ich das Ich sehe nicht, wie das Maven-Plugin Ihnen helfen kann.
Was genau produziert Jacoco Agent?
Nur Abdeckungsdaten im
.exec
Format. Sonar kann es dann lesen.Muss Jacoco wissen, wo sich meine Java-Klassen befinden?
Nein, Sonar, aber kein Jacoco. Wenn Sie den
mvn sonar:sonar
Weg zum Unterricht gehen, kommt er ins Spiel.Was ist also mit dem Ameisenskript?
Es muss in Ihrem Jenkins-Arbeitsbereich präsentiert werden. Mein Ameisenskript, ich habe es
jacoco.xml
so genannt:Zwei obligatorische Parameter, die Sie beim Aufrufen dieses Skripts übergeben sollten,
-Dworkspace=$WORKSPACE
verwenden es, um auf Ihren Jenkins-Arbeitsbereich zu verweisen und-Djacoco.host=yourappserver.com
ohne zu hostenhttp://
jacocoant.jar
Beachten Sie auch, dass ich meine in $ {workspace} /tools/jacoco/jacocoant.jar platziereWas soll ich als nächstes tun?
Haben Sie Ihren App-Server mit jacocoagent.jar gestartet?
Haben Sie Ant Script und jacocoant.jar in Ihren Jenkins-Arbeitsbereich eingefügt?
Wenn ja, besteht der letzte Schritt darin, einen Jenkins-Build zu konfigurieren. Hier ist die Strategie:
jacocoReset
auf, um alle zuvor gesammelten Daten zurückzusetzen.jacocoReport
, um einen Bericht zu erhaltenWenn alles in Ordnung ist, sehen Sie
it-jacoco.exec
in Ihrem Build-Arbeitsbereich.Schauen Sie sich den Screenshot an, den ich auch
ant
in meinem Arbeitsbereich in$WORKSPACE/tools/ant
dir installiert habe , aber Sie können einen verwenden, der in Ihren Jenkins installiert ist.Wie kann man diesen Bericht im Sonar pushen?
Maven
sonar:sonar
erledigt den Job (vergessen Sie nicht, ihn zu konfigurieren) und zeigt auf die Hauptdatei pom.xml, damit er alle Module durchläuft. Verwenden Sie densonar.jacoco.itReportPath=$WORKSPACE/it-jacoco.exec
Parameter, um dem Sonar mitzuteilen, wo sich Ihr Integrationstestbericht befindet. Jedes Mal, wenn neue Modulklassen analysiert werden, wird nach Informationen zur Abdeckung in gesuchtit-jacoco.exec
.Ich habe bereits jacoco.exec in meinem `target`-Verzeichnis,` mvn sonar: sonar` ignoriert / entfernt es
Standardmäßig
mvn sonar:sonar
wirdclean
Ihr Zielverzeichnis gelöscht, um diessonar.dynamicAnalysis=reuseReports
zu vermeiden.quelle
NEUER WEG SEIT VERSION 0.7.7
Seit Version 0.7.7 gibt es eine neue Möglichkeit, einen aggregierten Bericht zu erstellen:
Sie erstellen ein separates 'Bericht'-Projekt, das alle erforderlichen Berichte sammelt (Jedes Ziel im Aggregator-Projekt wird vor seinen Modulen ausgeführt, daher kann es nicht verwendet werden).
Das Root-Pom sieht folgendermaßen aus (vergessen Sie nicht, das neue Berichtsmodul unter Module hinzuzufügen):
Die Poms von jedem Submodul müssen überhaupt nicht geändert werden. Der Pom aus dem Berichtsmodul sieht folgendermaßen aus:
Ein vollständiges Beispiel finden Sie hier .
quelle
Ich werde meine Lösung veröffentlichen, da sie sich geringfügig von anderen unterscheidet, und ich habe auch einen guten Tag gebraucht, um sie mithilfe der vorhandenen Antworten richtig zu machen.
Für ein Maven-Projekt mit mehreren Modulen:
Wenn das
WAR
Projekt die Hauptwebanwendung ist, sindLIB
1 und 2 zusätzliche Module,WAR
vonTEST
denen die Integrationstests abhängen .TEST
Startet eine eingebettete Tomcat-Instanz (nicht über das Tomcat-Plugin), führt dasWAR
Projekt aus und testet sie über eine Reihe von JUnit-Tests. DieWAR
undLIB
Projekte haben beide ihre eigenen Unit-Tests.Das Ergebnis all dessen ist, dass die Integration und die Abdeckung von Komponententests getrennt sind und in SonarQube unterschieden werden können.
ROOT pom.xml
WAR
,LIB
UndTEST
pom.xml
die die JaCoCo Plugins Ausführung erben.TEST pom.xml
Ich fand auch Petri Kainulainens Blog-Post 'Erstellen von Code-Coverage-Berichten für Unit- und Integrationstests mit dem JaCoCo Maven Plugin' für die JaCoCo-Setup-Seite von Nutzen.
quelle
agent-for-it
Dies ist nur erforderlich, wenn die Tests imTEST
Modul ausgeführt werden. In der aktuellen Konfiguration wird es jedoch für jedes andere Modul ausgeführt, für das es keinen Wert hat. Die Verbesserung wäre,agent-for-ut
in allen anderen Modulenagent-for-it
gelaufen zu sein und nur in zu laufenTEST
.Die Konfiguration, die ich in meinem übergeordneten POM verwende, wo ich separate Einheiten- und Integrationstestphasen habe.
Ich konfiguriere die folgenden Eigenschaften in den übergeordneten POM-Eigenschaften
Ich platziere die Plugin-Definitionen unter Plugin-Verwaltung.
Beachten Sie, dass ich eine Eigenschaft für die Argumente safefire (surefireArgLine) und failafe (failafeArgLine) definiere, damit jacoco den Java-Agenten so konfigurieren kann, dass er bei jedem Test ausgeführt wird.
Unter pluginManagement
Und im Build-Bereich
Und im Berichtsbereich
quelle
<append>true</append>
Konfiguration unter denprepare-agent
Abschnitten ...Es gibt einen Weg, dies zu erreichen. Die Magie besteht darin, eine kombinierte jacoco.exec-Datei zu erstellen. Und mit Maven 3.3.1 gibt es eine einfache Möglichkeit, dies zu erreichen. Hier mein Profil:
Wenn Sie dieses Profil zu Ihrem Eltern-Pom hinzufügen und anrufen, erhalten
mvn clean install sonar:sonar -DrunSonar
Sie die vollständige Abdeckung.Die Magie hier ist
maven.multiModuleProjectDirectory
. Dieser Ordner ist immer der Ordner, in dem Sie Ihren Maven-Build gestartet haben.quelle
mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.0.905:sonar -DrunSonar
aufgrund einesA required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.0.1:sonar: org/sonar/batch/bootstrapper/IssueListener
Fehlers ein Sonar mit Befehl ausführen musste .Ich habe eine andere Lösung für neue Sonar-Versionen gefunden, bei der das binäre Berichtsformat von JaCoCo (* .exec) veraltet ist und das bevorzugte Format XML (SonarJava 5.12 und höher) ist. Die Lösung ist sehr einfach und ähnelt der vorherigen Lösung mit * .exec-Berichten im übergeordneten Verzeichnis aus diesem Thema: https://stackoverflow.com/a/15535970/4448263 .
Angenommen, unsere Projektstruktur ist:
Sie benötigen die folgende Konfiguration des Maven Build Plugins im POM des Aggregatprojekts:
Dann baue ein Projekt mit maven:
Und für Sonar sollten Sie die Eigenschaft in der Verwaltungs-GUI festlegen:
oder über die Kommandozeile:
Beschreibung
Dadurch werden Binärberichte für jedes Modul in Standardverzeichnissen erstellt :
target/jacoco.exec
. Anschließend werden XML-Berichte für jedes Modul in Standardverzeichnissen erstellt :target/site/jacoco/jacoco.xml
. Anschließend wird für jedes Modul im benutzerdefinierten Verzeichnis ein aggregierter Bericht erstellt, der für jedes Modul${project.basedir}/../target/site/jacoco-aggregate/
relativ zum übergeordneten Verzeichnis ist. Für Modul A und Modul B ist dies ein gemeinsamer PfadmoduleC/target/site/jacoco-aggregate/
.Da Modul B von Modul A abhängt, wird Modul B zuletzt erstellt und sein Bericht wird als aggregierter Abdeckungsbericht in Sonar für beide Module A und B verwendet.
Zusätzlich zum Aggregatbericht benötigen wir einen normalen Modulbericht, da JaCoCo-Aggregatberichte nur Abdeckungsdaten für Abhängigkeiten enthalten.
Zusammen bieten diese beiden Arten von Berichten vollständige Abdeckungsdaten für Sonar.
Es gibt eine kleine Einschränkung: Sie sollten in der Lage sein, einen Bericht in das übergeordnete Verzeichnis des Projekts zu schreiben (sollte über die Berechtigung verfügen). Oder Sie können die Eigenschaft
jacoco.skip=true
in der pom.xml (moduleC) des Root-Projekts undjacoco.skip=false
in Modulen mit Klassen und Tests (moduleA und moduleB) festlegen.quelle
quelle
Als Sonare
sonar.jacoco.reportPath
,sonar.jacoco.itReportPath
undsonar.jacoco.reportPaths
alle sind veraltet , sollten Siesonar.coverage.jacoco.xmlReportPaths
jetzt verwenden. Dies hat auch Auswirkungen, wenn Sie ein Maven-Projekt mit mehreren Modulen mit Sonar und Jacoco konfigurieren möchten.Wie @Lonzak wies darauf hin , da Sonar 0.7.7 können Sie Sonars Bericht aggragation Ziel verwenden. Geben Sie einfach die folgende Abhängigkeit in Ihr übergeordnetes Element ein:
Da aktuelle Versionen des jacoco-maven-Plugins mit den XML-Berichten kompatibel sind, wird für jedes Modul in seinem eigenen Zielordner ein Site- / Jacoco-Aggregat-Ordner erstellt, der eine
jacoco.xml
Datei enthält.Verwenden Sie den folgenden Befehl, damit Sonar alle Module kombiniert:
Um meine Antwort kurz und präzise zu halten, habe ich die
maven-surefire-plugin
undmaven-failsafe-plugin
Abhängigkeiten nicht erwähnt . Sie können sie einfach ohne andere Konfiguration hinzufügen:quelle
Sie können eine Ant-Task namens Merge on Maven aufrufen, um alle Coverage-Dateien (* .exec) in derselben Datei zusammenzufassen.
Wenn Sie Unit-Tests ausführen, verwenden Sie das Phase- Prepare-Paket . Wenn Sie einen Integrationstest ausführen, verwenden Sie den Post-Integration-Test .
Diese Seite enthält ein Beispiel dafür, wie man Jacoco Ant Task im Maven-Projekt aufruft
Sie können diese zusammengeführte Datei auf dem Sonar verwenden.
quelle
Für Unit-Tests UND Integrationstests können Sie das Maven-Surefire-Plugin und das Maven-Fail-Safe-Plugin mit eingeschränkten Ein- / Ausschlüssen verwenden. Ich habe mit CDI gespielt, als ich mit Sonar / Jacoco in Kontakt getreten bin, also bin ich in diesem Projekt gelandet:
https://github.com/FibreFoX/cdi-sessionscoped-login/
Vielleicht hilft es dir ein bisschen. In meiner pom.xml verwende ich implizit "-javaagent", indem ich die argLine-Option im Konfigurationsabschnitt der angegebenen Test-Plugins setze. Die explizite Verwendung von ANT in MAVEN-Projekten würde ich nicht versuchen, für mich ist es zu viel, zwei Welten zu mischen.
Ich habe nur ein Maven-Projekt mit einem Modul, aber vielleicht hilft es Ihnen, Ihr Projekt an die Arbeit anzupassen.
Hinweis: Möglicherweise sind nicht alle Maven-Plugins auf dem neuesten Stand, möglicherweise wurden einige Probleme in späteren Versionen behoben
quelle
Dieses Beispiel funktioniert sehr gut für mich:
quelle