JaCoCo with microservice project architecture? - gradle

My project consists of 6 microservices in java and I am trying to figure out how to merge the html reports from Jacoco into one overall coverage report. As it stands now I end up with a report for each service and it would be nice to have an aggregated one so I can more easily put it into our CI for visibility etc.
I've tried various things I've found on web searches, but I end up with an empty coverage file when I try those suggestions.
Here is my gradle file:
subprojects {
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.7+"
reportsDir = file("$buildDir/reports/customJacocoReportDir")
}
jacocoTestReport {
reports {
xml.enabled true
csv.enabled false
html.destination "$buildDir/reports/jacocoHtml"
}
}
test {
finalized by jacocoTestReport
...
}
I run gradle test to run the tests and get the report output per service using the above, but I am really stumped on how to merge them into a single html report. If anyone has done this successfully please let me know. Thank you.

At the moment we have the same kind of problem, the jacoco agent has a maven goal called "merge". You can specify the source files and run it:
jacoco:merge
Full name:
org.jacoco:jacoco-maven-plugin:0.7.8-SNAPSHOT:merge
Description:
Mojo for merging a set of execution data files (*.exec) into a single file
Attributes:
Requires a Maven project to be executed.
The goal is thread-safe and supports parallel builds.
Since version: 0.6.4.
Binds by default to the lifecycle phase: generate-resources.
<fileSets>
<fileSet implementation="org.apache.maven.shared.model.fileset.FileSet">
<directory>${project.build.directory}</directory>
<includes>
<include>*.exec</include>
</includes>
</fileSet>
</fileSets>
Actual link: http://www.eclemma.org/jacoco/trunk/doc/merge-mojo.html
Hope it helps :D

I use jacoco:report-aggregate goal for this purpose.
According its documentation, I have a special module which is created just to run jacoco aggregation (it executes jacoco:report-aggregate during the "package" phase). It depends on modules whose test coverage I want to combine into a single report. This is also described by techgobi.blogspot.com.
As of version 0.8.8 of jacoco-maven-plugin, it has non-obvious peculiarity:
it works only if unit tests are executed by the same command as "jacoco:report-aggregate" goal.
In other words, if I use command-line to run unit tests from module A, and then I execute another command to run unit tests from module B, and then I execute "package" in the special module to trigger "jacoco:report-aggregate" - it won't work, JaCoCo will generate an empty aggregated report. In another scenario, it won't be empty, but the aggregated coverage will be 0%. It works only if unit test are executed by same command.

Related

How to write a Maven plugin IT test that correctly fails its build, resulting in an overall pass?

When generating a skeleton Maven plugin from archetype, the new project includes a Maven project under the src/it directory. It is an integration it (hinted at by the it dir name) and fresh out-of-the-box it passes when run during Maven's integration-test phase.
There are nearly 10 such IT Maven projects, a subset of which intentionally result in BUILD FAILURE, and attendant verify.groovy scripts that ensure those builds fail for the correct reason. Ideally each IT test sub-build that fails for the correct reason results in that IT test passing, but by including any of these failing IT tests as part of the whole integration test suite causes the overall Maven run to fail as well, which is incorrect in my case.
How do I coax Maven to run those failing Maven sub-builds, ignore their build results, but honor the results of their Groovy verification scripts?
Edit: One IT test (disabled) is committed here.
If you like to write an integration test which is intended to fail as a result
you have to express this via the invoker.properties file like this:
invoker.buildResult=failure
The full description of the file can be found in the documentation.

How to include Unit and Integration test in Sonar Code Coverage

I am using below commands to build my maven code.
Compile-
-DargLine="-DDB_SERVER=localhost -DDB_PORT=5432 -DDB_NAME=sample -DDB_USER=sample -DDB_PASSWORD=sample -DDB_MAX_POOL=10" -Dcom.sample.redis=false clean compiler:compile
Unit-Test Analysis-
DargLine=-DDB_SERVER=localhost -DDB_PORT=1234 -DDB_NAME=sample -DDB_USER=sample -DDB_PASSWORD=sample -DDB_MAX_POOL=10 -Dcom.sample.redis=false -Dcobertura:cobertura-integration-test -Dcobertura.aggregate=false -Dcobertura.report.format=xml integration-test test
And using below sonar properties to capture xml to publish in sonar.
sonar.projectKey=sample
sonar.projectName=sample
sonar.projectVersion=$PipelineId
sonar.modules=admin,client-api,common,om,serviceproviders
sonar.cobertura.reportPath=target/site/cobertura/coverage.xml
sonar.sources=.
sonar.skipPackageDesign=true
sonar.sourceEncoding=UTF-8
Being Multi module the code coverage is showing only 9.4%. Am I missing anything. I don't see any error logs as well.How can I achieve the same using coverage tool like Jacoco.
SonarQube - Version 5.1.1 - LGPL v3
Maven has a lifecycle Maven Lifecycle where each of the targets includes the ones before it. e.g. "test" includes "compile", "integration-test" includes "test", etc. You generally need to only include the target at the tip of the lifecycle. e.g. "mvn test" means (compile AND run the tests).
I'm thinking you want to run the "mvn verify" goal, which is compile, run tests and integration tests, and then run verifications (coverage checks, etc). Cobertura has a plugin that should integrate with maven and tap into various goals to run its pieces at appropriate times. I'm guessing you are messing up cobertura by having multiple targets and trying to break it into pieces - i.e. overwriting the instrumentation or something.
Similarly, you might find using jacoco easier than cobertura. It hides the instrumentation, and integrates pretty seemlessly with maven.
Good luck.

how to clean jacoco.exec after running integration tests in a multi-module project

I have a multimodule Maven project, it is analyzed using the Sonar Maven runner and coverage is done with Jacoco. For our integration tests we want to see the coverage across all modules (because they are integration tests after all).
Therefore we configure the jacoco-it.exec file to be in ${user.dir}, with the appendproperty to true. This way all modules append their information to the same location and coverage is calculated over all modules.
But since append is true the file will still be there on a next run, since it isn't placed in a directory that maven cleans. This leads to incorrect coverage reports.
What is the best way to clean up this file after a sonar run? Ideally I would like to configure this in the same pom profile as our jacoco/sonar configuration, so that no other projects need to remember to set a clean step in Jenkins or whereever. The sonar/jacoco configuration is in a company wide parent pom file.
Since you are using Maven, you could try and use the maven-antrun-plugin to delete the file.
I don't know how you run Sonar Maven, but you can either bind the maven-antrun-plugin task to a phase after the one the Sonar Maven Runner is bound to (and you would have the file deleted automatically and the end of each run) or you can call the maven-antrun-plugin from the command line.

Feed sonarqube jacoco widget with csv/html reports (instead of *.exec)

I got a root maven project, under which there are many independent modules (e.g. module_A, module_B, etc.).
One of these module is my integration-tests module, and it uses all the above external modules.
In order to have code coverage for all modules used by integration-tests, I use a workaround based on maven-ant (see this blog post).
Problem is:
The above generates csv/html report, yet sonarqube jacoco widget parses only jacoco*.exec files - which results in 0% code coverage.
Question is:
EDIT
here's an example project for the problem above.
You don't need to use that workaround. You can provide Sonar with integration tests coverage file with following property (you shall use it while executing sonar:sonar goal):
-Dsonar.jacoco.itReportPath=<coverage_file>
Here is detailed documentation:
http://docs.codehaus.org/display/SONAR/Code+Coverage+by+Integration+Tests+for+Java+Project
To sum up:
Compile all your modules.
Execute integration tests with jacoco enabled.
Execute Maven Sonar build adding mentioned property in command line.
I have prepared example project generating both unit and integration coverage results, you can check it here:
https://github.com/octosan/unit-and-integration-jacoco-coverage-with-sonar
You have to:
download newest Sonarqube version and start it
execute command:
mvn clean install sonar:sonar -Dsonar.jacoco.itReportPath=<absolute_path>/itest/target/jacoco-it.exec
add integration coverage widged in project dashboard in Sonar

SONAR importing cobertura.ser coverage reports to sonar server using mvn sonar:sonar?

I have a cobertura.ser file, that got generated while integration-test and system test. Now I want to import my coverage this to sonar server.
How can I achieve this, so while executing mvn sonar:sonar the coverage should consider external coberture.ser file?
Can I do this using sonar, where i can see overall coverage obtain during all test run?
You need to set the following paramater to tell Sonar to use a pre-generated report:
sonar.dynamicAnalysis=reuseReports
Secondly Sonar doesn't read the "cobertura.ser" file. It can be configured as follows to read the generated XML report (See cobertura docs):
sonar.cobertura.reportPath=target/reports/coverage.xml
Finally, my reference for all this stuff comes from the from the Sonar wiki:
http://docs.codehaus.org/display/SONAR/Advanced+Parameters
http://docs.codehaus.org/display/SONAR/Code+Coverage+by+Unit+Tests
http://docs.codehaus.org/display/SONAR/Code+Coverage+by+Integration+Tests
The Sonarsource tutorials are increasingly pushing JaCoCo. This appears to be an emerging standard (replacing the older defunct Emma project)

Resources