SonarQube + Maven + JaCoCo + GitLab CI:升级到 SonarQube 7.9.2 后,Sonar 开始显示 0% 的代码覆盖率
SonarQube + Maven + JaCoCo + GitLab CI: Sonar started to show 0% code coverage after upgrading to SonarQube 7.9.2
在我们将 SonarQube 升级到 Version 7.9.2 (build 30863), Community Edition
之后,运行 GitLab CI 管道结果显示 0.0%
覆盖率(从大约 86.2%
下降),尽管 Sonar 正在显示所有单元测试。
在 .gitlab-ci.yml
中执行的 Maven 构建如下所示:
- mvn test sonar:sonar -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_TOKEN}
显然这与臭名昭著的 sonar.coverage.jacoco.xmlReportPaths
和 sonar.jacoco.reportPaths
Sonar-JaCoCo 插件设置有关(参见 https://docs.sonarqube.org/pages/viewpage.action?pageId=1442166)。
查看管道作业日志后,我发现以下内容(项目名称混淆为 myProject
):
SonarQube升级前:
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/builds/myProject/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=87ms
[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). Please check that the JaCoCo plugin is installed on your SonarQube Instance.
[INFO] Analysing /builds/myProject/target/jacoco.exec
[INFO] Sensor JaCoCoSensor [java] (done) | time=206ms
SonarQube升级后:
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/builds/myProject/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=86ms
[INFO] Sensor JavaXmlSensor [java]
[INFO] 1 source files to be analyzed
[INFO] Sensor JavaXmlSensor [java] (done) | time=302ms
因此在 sonar.jacoco.reportPaths
设置方面显然存在一些差异。
值得注意的是,我没有明确设置这两个设置中的任何一个。
如何修复 JaCoCo 报告的解析以使其正常工作(无论旧设置还是新设置)?
快速回答
将 mvn test
替换为 mvn verify
。不需要明确的设置声明。
我的调查过程
我尝试使用显式设置值默认设置执行构建。
1) 弃用设置的显式默认值:-Dsonar.jacoco.reportPaths=target/jacoco.exec
.
这会产生以下日志,表明此设置将不再适用于新的 Sonar:
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=57ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/builds/myProject/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=23ms
[INFO] Sensor Removed properties sensor [java]
[WARNING] Property 'sonar.jacoco.reportPaths' is no longer supported. Use JaCoCo's xml report and sonar-jacoco plugin.
[INFO] Sensor Removed properties sensor [java] (done) | time=1ms
显然,覆盖率保持在 0.0%
。
另请参阅关于此主题的 SO 相关 Ant 问题:Display Sonar Code Coverage with jacoco.exec file in Sonar LTS 7.9.2。
2) 新设置的显式默认值:-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
注意: 虽然这个默认值没有(出于某种原因)记录在 https://docs.sonarqube.org/pages/viewpage.action?pageId=1442166 上,但我只是通过搜索 jacoco.xml
找到了它在我的本地 target
目录中。
覆盖率保持在 0.0%
,GitLab CI 作业日志开始终于显示出一些清晰的内容:
[INFO] Sensor SonarCSS Rules [cssfamily] (done) | time=1ms
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[WARNING] Report doesn't exist: '/builds/myProject/target/site/jacoco/jacoco.xml'
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=4ms
[INFO] Sensor SurefireSensor [java]
! 很遗憾,在没有明确设置的情况下运行没有写这个日志。这将大大简化调查。
所以现在我们有了一个理解:/target/site
不是在我的 GitLab CI 管道上生成的。显然,这是因为该脚本仅包含 mvn test
,通过 Maven Build Lifecycle.
还不够远
查看 Maven + Sonar 示例:它们包含 mvn verify sonar:sonar
或 mvn install sonar:sonar
。
因此我们开始:
3) mvn verify
+ 新设置的显式默认值:-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
这成功了!覆盖范围显示在 SonarQube 上,并且 JaCoCo 相关日志部分中没有错误:
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=94ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/builds/myProject/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=92ms
[INFO] Sensor JavaXmlSensor [java]
[INFO] Sensor JavaXmlSensor [java] (done) | time=7ms
4) mvn verify
没有显式设置。
所以最后我在没有任何设置值的情况下尝试了,它起作用了:
- mvn verify sonar:sonar -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_TOKEN}
总结
- 旧
sonar.jacoco.reportPaths
设置不适用于新的 SonarQube 版本 (7.9.2+)。
- 新
sonar.coverage.jacoco.xmlReportPaths
设置的默认值为 target/site/jacoco/jacoco.xml
。
- 根本原因是
/target/site/jacoco
目录没有生成(包括jacoco.xml
和JaCoCo报告的所有其他文件)
- 我所要做的就是将
mvn test
替换为mvn verify
。
- 当
sonar.coverage.jacoco.xmlReportPaths
的值未明确设置时,Sonar 的主要缺陷是不写入有关 "report file not found" 的错误日志。 SonarQube 开发人员修复它会很好。
请使用以下内容
mvn clean verify sonar:sonar -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_TOKEN}
在我们将 SonarQube 升级到 Version 7.9.2 (build 30863), Community Edition
之后,运行 GitLab CI 管道结果显示 0.0%
覆盖率(从大约 86.2%
下降),尽管 Sonar 正在显示所有单元测试。
在 .gitlab-ci.yml
中执行的 Maven 构建如下所示:
- mvn test sonar:sonar -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_TOKEN}
显然这与臭名昭著的 sonar.coverage.jacoco.xmlReportPaths
和 sonar.jacoco.reportPaths
Sonar-JaCoCo 插件设置有关(参见 https://docs.sonarqube.org/pages/viewpage.action?pageId=1442166)。
查看管道作业日志后,我发现以下内容(项目名称混淆为 myProject
):
SonarQube升级前:
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/builds/myProject/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=87ms
[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). Please check that the JaCoCo plugin is installed on your SonarQube Instance.
[INFO] Analysing /builds/myProject/target/jacoco.exec
[INFO] Sensor JaCoCoSensor [java] (done) | time=206ms
SonarQube升级后:
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/builds/myProject/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=86ms
[INFO] Sensor JavaXmlSensor [java]
[INFO] 1 source files to be analyzed
[INFO] Sensor JavaXmlSensor [java] (done) | time=302ms
因此在 sonar.jacoco.reportPaths
设置方面显然存在一些差异。
值得注意的是,我没有明确设置这两个设置中的任何一个。
如何修复 JaCoCo 报告的解析以使其正常工作(无论旧设置还是新设置)?
快速回答
将 mvn test
替换为 mvn verify
。不需要明确的设置声明。
我的调查过程
我尝试使用显式设置值默认设置执行构建。
1) 弃用设置的显式默认值:-Dsonar.jacoco.reportPaths=target/jacoco.exec
.
这会产生以下日志,表明此设置将不再适用于新的 Sonar:
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=57ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/builds/myProject/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=23ms
[INFO] Sensor Removed properties sensor [java]
[WARNING] Property 'sonar.jacoco.reportPaths' is no longer supported. Use JaCoCo's xml report and sonar-jacoco plugin.
[INFO] Sensor Removed properties sensor [java] (done) | time=1ms
显然,覆盖率保持在 0.0%
。
另请参阅关于此主题的 SO 相关 Ant 问题:Display Sonar Code Coverage with jacoco.exec file in Sonar LTS 7.9.2。
2) 新设置的显式默认值:-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
注意: 虽然这个默认值没有(出于某种原因)记录在 https://docs.sonarqube.org/pages/viewpage.action?pageId=1442166 上,但我只是通过搜索 jacoco.xml
找到了它在我的本地 target
目录中。
覆盖率保持在 0.0%
,GitLab CI 作业日志开始终于显示出一些清晰的内容:
[INFO] Sensor SonarCSS Rules [cssfamily] (done) | time=1ms
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[WARNING] Report doesn't exist: '/builds/myProject/target/site/jacoco/jacoco.xml'
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=4ms
[INFO] Sensor SurefireSensor [java]
! 很遗憾,在没有明确设置的情况下运行没有写这个日志。这将大大简化调查。
所以现在我们有了一个理解:/target/site
不是在我的 GitLab CI 管道上生成的。显然,这是因为该脚本仅包含 mvn test
,通过 Maven Build Lifecycle.
查看 Maven + Sonar 示例:它们包含 mvn verify sonar:sonar
或 mvn install sonar:sonar
。
因此我们开始:
3) mvn verify
+ 新设置的显式默认值:-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
这成功了!覆盖范围显示在 SonarQube 上,并且 JaCoCo 相关日志部分中没有错误:
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=94ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/builds/myProject/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=92ms
[INFO] Sensor JavaXmlSensor [java]
[INFO] Sensor JavaXmlSensor [java] (done) | time=7ms
4) mvn verify
没有显式设置。
所以最后我在没有任何设置值的情况下尝试了,它起作用了:
- mvn verify sonar:sonar -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_TOKEN}
总结
- 旧
sonar.jacoco.reportPaths
设置不适用于新的 SonarQube 版本 (7.9.2+)。 - 新
sonar.coverage.jacoco.xmlReportPaths
设置的默认值为target/site/jacoco/jacoco.xml
。 - 根本原因是
/target/site/jacoco
目录没有生成(包括jacoco.xml
和JaCoCo报告的所有其他文件) - 我所要做的就是将
mvn test
替换为mvn verify
。 - 当
sonar.coverage.jacoco.xmlReportPaths
的值未明确设置时,Sonar 的主要缺陷是不写入有关 "report file not found" 的错误日志。 SonarQube 开发人员修复它会很好。
请使用以下内容
mvn clean verify sonar:sonar -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_TOKEN}