1
votes

I use Jacoco, Sonar, Maven to report unit test coverage, this is a springboot project and please see my project arch as below:

web
 |-src/test/java --unit test classes
 |-target/
 |-pom.xml
service
 |-pom.xml
pom.xml
target
 |-sonar
 |-jacoco.exec

My maven config in parent pom.xml:

<plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.8</version>
                <configuration>
                    <destFile>${project.basedir}/../target/jacoco.exec</destFile>
                    <append>true</append>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-agent</goal>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

web/pom.xml:

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M4</version>
                <configuration>
                    <skipTests>false</skipTests>
                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
                    <testFailureIgnore>true</testFailureIgnore>
                    <argLine>${argLine}</argLine>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit4</artifactId>
                        <version>3.0.0-M4</version>
                    </dependency>
                </dependencies>
            </plugin>

Step 1: run mvn clean org.jacoco:jacoco-maven-plugin:0.7.8:prepare-agent package -Dmaven.test.failure.ignore=true -q

file jacoco.exec was generated in folder target/jacoco.exec

Step 2: run below cmd:

mvn sonar:sonar -Dsonar.projectKey="projectName" -Dsonar.login={key} -Dsonar.host.url=http://ip:port -Dsonar.jdbc.url=jdbc:postgresql://ip:port/sonar -Dsonar.java.binaries=target/sonar

sonar folder was generated

sonar
 |-.sonar_lock
 |-projectName.pdf
 |-report-task.txt

I checked projectName.pdf,sonar analysis was there but test coverage was 0, only unit test count is correct, then i open Sonarqube find test coverage also 0.

Finally, i checked sonar log and found below log: No Jacoco...

mvn sonar:sonar log:

[INFO] Sensor JaCoCoSensor [java]
[WARNING] Property 'sonar.jacoco.reportPaths' is deprecated (JaCoCo binary format). 'sonar.coverage.jacoco.xmlReportPaths' should be used instead (JaCoCo XML format).
[INFO] No JaCoCo analysis of project coverage can be done since there are no class files.
[INFO] Sensor JaCoCoSensor [java] (done) | time=1ms
[INFO] Sensor JavaXmlSensor [java]

Question:

  1. Why sonar couldn't find Jacoco class files, does it find jacoco.exec or other file.
  2. How to genetate unit test coverage in Sonar.

Thanks!

1
sonar.jacoco.reportPaths should refer to classes that code compiled, so i copied classes from web/target/classes to target/classes, then updatesonar.jacoco.reportPaths=target/classes, rerun mvn sonar:sonar..., it can find jacoco.exec and code coverage in sonarqube is correct, will check how to run it without copy classes from web/target/classes. - Rollsbean

1 Answers

1
votes

After checked, i resolved this issue.

The key to solve this issue is sonar parameter sonar.java.binaries, this parameter is required and should set the path where your byte code generated, see sonarqube doc: https://docs.sonarqube.org/latest/analysis/languages/java/

sonar.java.binaries (required):

Comma-separated paths to directories containing the compiled bytecode files corresponding to your source files.

So what should i do is to update mvn sonar:sonar's params, change

-Dsonar.java.binaries=target/sonar

to Dsonar.java.binaries=target , target/sonar doesn't have classes but in target there are classes.

After doing that jacoco analysis will run and the output is that:

[INFO] Sensor JaCoCoSensor [java]
[WARNING] Property 'sonar.jacoco.reportPaths' is deprecated (JaCoCo binary format). 'sonar.coverage.jacoco.xmlReportPaths' should be used instead (JaCoCo XML format).
[INFO] Analysing /Users/rollsbean/workRepo/my-project/common/../target/jacoco.exec
[INFO] Sensor JaCoCoSensor [java] (done) | time=56ms
[INFO] Sensor JavaXmlSensor [java]
[INFO] 1 source files to be analyzed
[INFO] Sensor JavaXmlSensor [java] (done) | time=7ms
...
[INFO] Sensor JaCoCoSensor [java]
[WARNING] Property 'sonar.jacoco.reportPaths' is deprecated (JaCoCo binary format). 'sonar.coverage.jacoco.xmlReportPaths' should be used instead (JaCoCo XML format).
[INFO] Analysing /Users/rollsbean/workRepo/my-project/web/../target/jacoco.exec
[INFO] Sensor JaCoCoSensor [java] (done) | time=245ms
[INFO] Sensor JavaXmlSensor [java]
[INFO] 1 source files to be analyzed
[INFO] 1/1 source files have been analyzed
[INFO] Sensor JavaXmlSensor [java] (done) | time=206ms
...

That's all, hope it will help you.