Mamy wielomodułowy wielojęzyczny program maven java z analizą zasięgu z jacoco. Główną częścią modułów jest backend (kod Java) z interfejsem API REST, a nasz moduł webapp zawiera frontend (AngularJS) i testy integracji w java. Nasz plik Jacoco-IT.exec zawiera około 100 kilobajtów danych, więc możemy zgadnąć, że niektóre dane pokrycia dla testów integracyjnych mogłyby zostać zebrane. Niemniej jednak nie możemy zobaczyć żadnego pokrycia w SonarQube (przy użyciu wersji 5.0 i 4.5)Pokrycie testu integracyjnego w SonarQube z wtyczki JaCoCo Maven pokazujące 0%
Prowadzimy zbudować projekt i uruchomić testy integracji z
mvn clean install
i analizować dane z
mvn sonar:sonar
Projekt jest skonfigurowany jako wielojęzykowy, ale po prostu analizujemy kod Java jeszcze (używaliśmy konfiguracji monolanguage, ale nie było różnicy w wynikach związanych z danymi pokrycia)
Nasz nadrzędny POM:
<properties>
<hibernate.version>4.2.2.Final</hibernate.version>
<spring.version>3.2.3.RELEASE</spring.version>
<resteasy.version>3.0.4.Final</resteasy.version>
<cucumber.version>1.1.3</cucumber.version>
<selenium-java.version>2.33.0</selenium-java.version>
<!-- Sonar -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.itReportPath>${project.basedir}/../target/jacoco-it.exec</sonar.jacoco.itReportPath>
<jacoco.dataFile>${project.basedir}/../target/jacoco-it.exec</jacoco.dataFile>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<debug>true</debug>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-report-integration</id>
<goals>
<goal>report-integration</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
</plugin>
</plugins>
<pluginManagement>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.2.201409121644</version>
</plugin>
</pluginMangement>
</build>
Nasz POM z webapp z testami integracji:
<properties>
<sonar.sources>src/main</sonar.sources>
</properties>
<build>
<finalName>web</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.7.v20120910</version>
<configuration>...</configuration>
<executions>...</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<!-- The destination file for the code coverage report has to be set to the same value
in the parent pom and in each module pom. Then JaCoCo will add up information in
the same report, so that, it will give the cross-module code coverage. -->
<destFile>${project.basedir}/../target/jacoco-it.exec</destFile>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.16</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Jak widać w naszym rodzicem POM mamy skonfigurowany itReportPath być w tym samym katalogu dla wszystkich Moduły. Tak więc, gdy Sonar analizuje wszystkie moduły, odczytuje zawsze te same dane pokrycia i powinien dopasować je do informacji debugowania z plików binarnych bieżącego modułu. Podczas fazy analizy Maven (mvn sonar: sonar) otrzymujemy jakieś wiadomości, których nie jesteśmy pewni, czy są one problem:
dla wszystkich modułów java otrzymujemy linie folloing:
[INFO] [17:30:42.992] Sensor SurefireSensor...
[INFO] [17:30:42.992] parsing \git\airport-core\rest\target\surefire-reports
[INFO] [17:30:43.009] Sensor SurefireSensor done: 17 ms
[INFO] [17:30:43.009] Sensor JaCoCoItSensor...
[INFO] [17:30:43.010] Analysing \git\airport-core\rest\..\target\jacoco-it.exec
[INFO] [17:30:43.018] No information about coverage per test.
[INFO] [17:30:43.018] Sensor JaCoCoItSensor done: 9 ms
[INFO] [17:30:43.018] Sensor JaCoCoOverallSensor...
[INFO] [17:30:43.027] Analysing \git\airport-core\rest\target\sonar\jacoco-overall.exec
[INFO] [17:30:43.046] No information about coverage per test.
[INFO] [17:30:43.046] Sensor JaCoCoOverallSensor done: 28 ms
Is "Brak informacji o zasięgu na test." problem? Ok, nie wiemy, który test spowodował pokrycie, ale powinniśmy uzyskać inną wartość w SonarQube niż 0%
i dla naszego modułu webapp, który nie zawiera żadnych źródeł/klas java, z wyjątkiem samych źródeł testu integracji, otrzymujemy następujące linie:
[INFO] [17:30:48.370] Sensor JaCoCoItSensor...
[INFO] [17:30:48.370] No JaCoCo analysis of project coverage can be done since there is no class files.
[INFO] [17:30:48.370] Sensor JaCoCoItSensor done: 0 ms
Nie powinno to stanowić problemu, ponieważ w tym module nie ma klas. Czy ta obserwacja jest poprawna?
Do głównej części nasza konfiguracja bazuje na oficjalnej konfiguracji demo SonarCube (https://github.com/SonarSource/sonar-examples/tree/master/projects/languages/java/code-coverage/combined%20ut-it/combined-ut-it-multimodule-maven-jacoco), właśnie dodaliśmy cel "przygotować-agent-integracja". I oczywiście zmieniono go na projekt wielojęzyczny.
Znaleźliśmy wiele zdeprawowanych informacji w Internecie (ustawienia argLine itd.), Które nic nie zmieniły dla nas.
Linki do dokumentacji i samouczków użyliśmy:
- http://docs.sonarqube.org/display/SONAR/Code+Coverage+by+Integration+Tests+for+Java+Project
- http://www.sonarqube.org/measure-coverage-by-integration-tests-with-sonar-updated/
gdzie znajdują się pliki klas? Maven używa domyślnej lokalizacji, która nie zawsze jest mapowana przez wszystkie katalogi wyjściowe wtyczek. Nie jestem pewien, ale myślę, że maven używa "/ target", ale niektóre wtyczki mogą używać "/ bin" (lub odwrotnie). Aby tego uniknąć, można ustawić –
Krummy
, gdy klasy są w docelach/klasach, z wyjątkiem aplikacji webowej, która właśnie przetestowała. tam klasy są w klasach docelowych/testowych. –
podczas analizy sonaru uruchom również wypisze poprawną ścieżkę do plików binarnych. –