Sonar 和 Jacoco:由于没有类文件,因此无法对项目覆盖率进行 JaCoCo 分析

Posted

技术标签:

【中文标题】Sonar 和 Jacoco:由于没有类文件,因此无法对项目覆盖率进行 JaCoCo 分析【英文标题】:Sonar and Jacoco: No JaCoCo analysis of project coverage can be done since there are no class files 【发布时间】:2021-02-09 12:00:50 【问题描述】:

我使用 Jacoco、Sonar、Maven 报告单元测试覆盖率,这是一个 springboot 项目,请参阅我的项目架构如下:

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

我在父级 pom.xml 中的 maven 配置:

<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>

第一步:运行mvn clean org.jacoco:jacoco-maven-plugin:0.7.8:prepare-agent package -Dmaven.test.failure.ignore=true -q

文件jacoco.exec在文件夹target/jacoco.exec中生成

第二步:在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
 |-.sonar_lock
 |-projectName.pdf
 |-report-task.txt

我检查了projectName.pdf,有声纳分析,但测试覆盖率为 0,只有单元测试计数是正确的,然后我打开 Sonarqube 发现测试覆盖率也是 0。

最后,我检查了声纳日志,发现以下日志:No Jacoco...

mvn sonar:sonar日志:

[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]

问题

    为什么声纳找不到 Jacoco 类文件,它找到 jacoco.exec 或其他文件。 如何在 Sonar 中生成单元测试覆盖率。

谢谢!

【问题讨论】:

sonar.jacoco.reportPaths 应该引用代码编译的类,所以我将类从web/target/classes 复制到target/classes,然后更新sonar.jacoco.reportPaths=target/classes,重新运行mvn sonar:sonar...,它可以找到jacoco.exec 和sonarqube 中的代码覆盖率是正确的,将检查如何在不从 web/target/classes 复制类的情况下运行它。 【参考方案1】:

检查后,我解决了这个问题。

解决这个问题的关键是sonar参数sonar.java.binaries,这个参数是必需的,应该设置你的字节码生成的路径,见sonarqube doc:https://docs.sonarqube.org/latest/analysis/languages/java/

sonar.java.binaries (required):

包含已编译字节码的目录的逗号分隔路径 与您的源文件相对应的文件。

那我该怎么办就是更新mvn sonar:sonar的参数,改一下

-Dsonar.java.binaries=target/sonar

Dsonar.java.binaries=target , target/sonar 没有类,但在 target 中有类。

完成之后 jacoco 分析将运行,输出是:

[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
...

就这些了,希望对你有帮助。

【讨论】:

以上是关于Sonar 和 Jacoco:由于没有类文件,因此无法对项目覆盖率进行 JaCoCo 分析的主要内容,如果未能解决你的问题,请参考以下文章

使用 gradle / sonar / Jacoco 排除项目

解决Sonar扫描Lombok注解的代码没有覆盖率

源和测试类在不同模块中时的 JaCoCo 配置

将 Jacoco 代码覆盖率发布到声纳的命令

声纳 jacoco hybris

Kotlin Setup 的 Sonar Jacoco 不生成代码覆盖率