I am building a SonarQube 6.2 server which is already analyzing my Java 8/Gradle 3.3 projects. When adding JaCoCo to a multimodule gradle project, I realized that SonarQube
When you perform build JaCoCo Gradle Plugin will produce modA/build/jacoco/test.exec
and modB/build/jacoco/test.exe
that contain information about execution of tests in modA
and modB
respectively. SonarQube performs analysis of modules separately, so during analysis of modA
for the file TestedViaModB
it sees only modA/build/jacoco/test.exec
.
Most common trick to cross boundaries - is to collect all coverage information into single location. This can be done with JaCoCo Gralde Plugin
either by changing location - see destinationFile and destPath ( since information is appended to exec
file, don't forget to remove this single location prior to build, otherwise it will be accumulating information from different builds and not just from different modules ),
either by merging all files into single one - see JacocoMerge task. And then specify this single location to SonarQube as sonar.jacoco.reportPath.
Another trick: SonarQube 6.2 with Java Plugin 4.4 supports property sonar.jacoco.reportPaths allowing to specify multiple locations.
If you are interested in the solution with sonar.jacoco.reportPaths
(see answer of Godin), have looke at this gradle code:
tasks.getByName('sonarqube') {
doFirst {
// lazy initialize the property to collect all coverage files
def jacocoFilesFromSubprojects = subprojects.findAll {it.plugins.hasPlugin('jacoco')}
.collect {it.tasks.withType(Test)}.flatten().collect {it.jacoco.destinationFile}
sonarqube.properties {
property "sonar.jacoco.reportPaths", jacocoFilesFromSubprojects.join(',')
}
}
}
This will collect all coverage binary files and set them as comma-separated list to the sonar property. Considers all test tasks of sub projects where jacoco is applied and their jacoco destination file configured.