I have maven setup with multiple modules, the setup looks something like this
root module
- domain module
- repository module
- service module
- controllers module
Jacoco is correctly generating test coverage from unit tests and sonar is showing the correct percentage (let's say 20%). Surefire is used for unit tests.
For integration tests its more tricky, we use failsafe and integration tests generate jacoco-it.exec file which is scanned by sonar. My problem is that integration tests are located in the controllers module and it only shows test coverage of integration tests on classes that are inside controllers and not on classes that are in another module like service module. Because of this overall test coverage with integration tests increases to something like 21% instead of 35+%.
Is it possible to configure sonar and jacoco to measure test coverage with the integration tests of all classes instead of classes from same module only, if integration tests are in controllers module?
For reference, this is the relevant setup
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
...
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco.exec</destFile>
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>pre-integration-test</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco-it.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
</executions>
</plugin>
I run my tests with mvn verify and scanner with mvn sonar:sonar
You can aggregate your coverage reports by writing them all to the same destination file.
For example, we're only covering unit tests in our multi-module projects at the moment, so our parent pom contains:
<properties>
...
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
...
</properties>
and
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
<append>true</append>
</configuration>
<inherited>true</inherited>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
This results in a single aggregated report for all modules.
I expect that a similar pattern could be applied to your jacoco IT configuration.
Related
I am running jacoco plugin to generate html , xml and jacoco.exec reports to measure the coverage of the code tested by my testNg tests.
I am successful in the generation of these reports in my local as well as in Jenkins and all my unit test results are reflected in Sonar and it's showing me the coverage.
My jacoco.exec has both results of the coverage in the module and the dependent modules. I have verified this using eclemma plugin for eclipse.
I am not getting the coverage results in the dependent modules in Sonar.Does any one what I am doing wrong.
My plugin goes like this
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
and my goal is jacoco:report-aggregate
I got the answer from jacoco plugin coverage in multi-module
The following were the mistakes that I did which caused problem form me. In the properties of our pom
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
and in plugin
<destFile>${sonar.jacoco.reportPath}</destFile>
for me, the above statement flushed the jacoco.exec in different folders because of difference in maven module hierarchy as a result they never agrregated.
The second point is that the dependent module coverage will be only obtained only if it is a compile time dependency to the testing module.
My project setup is simple (all source available at github):
parent
↳ backend
↳ client
↳ integration-tests
And after runing maven:
mci sonar:sonar -Dsonar.host.url=http://localhost:9000 -Dsonar.login=12...9
I see that unit and integration tests are visible for sonar, but coverage from IT is not.
For Intelij IDEA jacoco-it.exec looks fine:
I'm assuming that culprit is here:
[INFO] Sensor JaCoCoSensor [java]
[INFO] No JaCoCo analysis of project coverage can be done since there is no class files.
[INFO] Sensor JaCoCoSensor [java] (done) | time=1ms
So I did small hack (in short: copied all source files to integration-test module):
<properties>
<sonar.sources>${basedir}/target/copied</sonar.sources>
</properties>
[...]
<!-- hack to generate coverage reports -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>generate-sources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${sonar.sources}</outputDirectory>
<resources>
<resource>
<directory>${basedir}/../backend/src/main/java</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${sonar.sources}</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
But now all my classes ale duplicated (sonar shows also classes from ../target/copied dir):
Sonar version: 6.5
Jacoco maven plugin: 0.7.5.201505241946 (also tried lastest 0.7.9)
Any ideas what should I do here?
Looks like I have answer for that question:
Report wasn't generated because post-unit-test execution was in the wrong phase. Instead of <phase>test</phase> I now have <phase>verify</phase>
I had a wrong goal for post-integration-test. The change was from <goal>report-integration</goal> to <goal>report-aggregate</goal>:
This goal allows me to create coverage reports when tests are in separate projects from the code under test.
Added properties:
<jacoco.itReportPath>${project.basedir}/../integrations-tests/target/jacoco-it.exec</jacoco.itReportPath> and
<sonar.jacoco.reportPaths>${jacoco.itReportPath},${project.build.directory}/jacoco-it.exec,${project.build.directory}/jacoco.exec</sonar.jacoco.reportPaths>
All those chages and update project available on github
I use mainly jacoco for coverage. You need to have a few things in place before you start
Enable and configure surefire plugin
Enable and configure the jacoco plugin
It's a one time configuration that you will build and forget, one of my projects serving as parent enables this feature. Feel free to check it out:
https://github.com/slixes/parent/blob/master/pom.xml
In my Maven/Java project, I want to make sure that I always get the loading of resources right -- some can be always fetched as Files, others get packaged into the final .jar and have to be fetched as streams.
I now would have thought that this is the ideal task for the Maven failsafe plugin: I simply JUnit-test the affected methods in the Unit tests (means, that the tests are run using the classes lying in the classes folder) using surefire and in the integration tests (means, the tests are run using the classes packed into the jar) using surefire.
But when I make a demo project that throws an Exception when run from the .jar and doesn't when run from Eclipse, both the unit tests and the integration tests calling the method do not throw an exception, means that failsafe doesn't use the packaged jar at all.
How can I tie it to the jar artifact only?
My pom.xml:
<project ...>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>packagingTest.MainClass</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
... Dependency to JUnit ...
</project>
I have a Java project consisting on multiple modules. Some functions for a common package are tested within the other modules. Sonar only shows the code coverage tested inside each package, how can I tell it to search in all the modules?
I am using SonarQube 4.5.4, Java 8 and JUnit 4.12
You have to provide SonarQube with a single JaCoCo report aggregating data from all the modules.
In the parent POM, define a location for this aggregated JaCoCo report:
<properties>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
</properties>
and configure JaCoCo (especially <destFile>)
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.6.201602180812</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>
In each module, tell JaCoCo to aggregate the coverage data to this global JaCoCo report file:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<destFile>${sonar.jacoco.reportPath}</destFile>
</configuration>
</plugin>
You can have a look at this project: https://github.com/racodond/sonar-css-plugin that produces an aggregated JaCoCo report used by SonarQube: https://sonarqube.com/dashboard/index?id=org.codehaus.sonar-plugins.css%3Acss
I have a maven project with integration tests stored in a module called my-project-tests, and production code spread across several other modules. I can get code coverage for the unit tests of individual modules by adding the following plugin instruction to the pom.xml:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.5.7.201204190339</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
I can then view the test report as described in the Netbeans wiki.
When I add this to my integration test module however, the report says "No data -- have you run your code yet?" (I have).
A jacoco.exec file is generated with a lot of data in it, I can't confirm if the data is correct. but a separate jacoco.xml file which Netbeans relies on is left mostly empty.
Is there a way to correctly produce and view code coverage of a multi-module project in Netbeans?
According to this bug, this is not supported in Netbeans: https://netbeans.org/bugzilla/show_bug.cgi?id=223319