
本文旨在解决在Sonarqube中Spring Boot应用使用JaCoCo和Maven进行代码覆盖率分析时,覆盖率始终显示0%的常见问题。核心在于JaCoCo和Surefire插件之间关于执行数据文件(.exec)和报告文件(.xml)路径及格式配置不一致。通过统一Maven pom.xml中的配置,确保JaCoCo代理正确生成数据,并将其转换为Sonarqube可识别的XML报告,即可实现正确的覆盖率展示。
1. 问题背景与现象分析
在使用Jenkins、Maven、JaCoCo和Sonarqube构建Spring Boot项目的CI/CD流水线时,一个常见的问题是Sonarqube上代码覆盖率始终显示为0%。这通常伴随着Maven构建日志中出现类似 [INFO] Skipping JaCoCo execution due to missing execution data file. 的警告信息。尽管单元测试已成功运行,但JaCoCo未能正确生成或找到其执行数据文件(通常是.exec文件),或者生成的报告文件(.xml)路径与Sonarqube期望的路径不符。
导致此问题的根本原因通常是JaCoCo Maven插件和Maven Surefire插件之间的配置不一致,特别是在以下几个方面:
- JaCoCo代理数据文件路径不一致: JaCoCo prepare-agent 目标生成.exec文件的位置与JaCoCo report 目标期望读取的位置不一致。
- Surefire插件未传递JaCoCo代理参数: Surefire插件在执行测试时,未能将JaCoCo代理所需的JVM参数传递给JVM。
- JaCoCo XML报告路径不一致: JaCoCo report 目标生成XML报告的路径与Sonarqube扫描器通过 sonar.coverage.jacoco.xmlReportPaths 属性配置的路径不一致。
2. 解决方案:统一Maven pom.xml 配置
解决此问题的关键在于确保所有相关插件和属性在 pom.xml 中保持高度一致性。
2.1 核心Maven pom.xml 属性配置
首先,在 pom.xml 的
1.8 3.1.0 UTF-8 ${basedir}/target/surefire-reports ${basedir}/target/jacoco_report/jacoco.xml
注意事项:
1.修正会员卡升级会员级别的判定方式2.修正了订单换货状态用户管理中心订单不显示的问题3.完善后台积分设置数据格式验证方式4.优化前台分页程序5.解决综合模板找回密码提示错误问题6.优化商品支付模块程序7.重写优惠卷代码8.优惠卷使用方式改为1卡1号的方式9.优惠卷支持打印功能10.重新支付模块,所有支付方式支持自动对账11.去掉规格库存显示12.修正部分功能商品价格显示4个0的问题13.全新的支
- sonar.coverage.jacoco.xmlReportPaths 必须指向JaCoCo最终生成的XML报告文件,而不是其二进制.exec文件。
- 路径应使用绝对路径或基于项目根目录的相对路径。
2.2 JaCoCo Maven 插件配置
JaCoCo插件负责在测试运行期间收集代码覆盖率数据,并将其转换为XML报告。其配置通常包含两个主要执行(execution):prepare-agent 和 report。
org.jacoco jacoco-maven-plugin 0.8.6 prepare-agent prepare-agent ${project.build.directory}/coverage-reports/jacoco-ut.exec surefireArgLine report test report ${project.build.directory}/coverage-reports/jacoco-ut.exec ${project.build.directory}/jacoco_report jacoco.xml
注意事项:
在 prepare-agent 中定义了JaCoCo代理生成.exec文件的位置。 在 report 中定义了JaCoCo报告生成器读取.exec文件的位置。这两个路径必须完全一致。 在 report 中定义了XML报告的输出目录。结合 jacoco.xml ,确保最终报告文件为 target/jacoco_report/jacoco.xml,这与 sonar.coverage.jacoco.xmlReportPaths 的配置相匹配。- propertyName surefireArgLine 是为了将JaCoCo代理参数传递给Surefire插件。
2.3 Maven Surefire 插件配置
Maven Surefire插件负责执行单元测试。它需要配置以接收并应用JaCoCo代理传递的JVM参数。
org.apache.maven.plugins maven-surefire-plugin 2.22.2 ${surefireArgLine} ${sonar.surefire.reportsPath}
注意事项:
-
${surefireArgLine} 是关键,它确保JaCoCo代理在测试执行时被激活并收集数据。 应该与 sonar.surefire.reportsPath 保持一致。
3. Jenkins 流水线配置
在Jenkins流水线中,需要确保Maven构建命令正确执行了JaCoCo的 prepare-agent 和 report 目标,并且Sonarqube扫描器能够找到生成的JaCoCo XML报告。
pipeline {
agent any
stages {
stage('Build and Test') {
steps {
// 清理、编译、运行测试并生成JaCoCo报告
// `mvn clean verify` 会触发 prepare-agent (在validate阶段), test (运行测试), report (在test阶段)
sh 'mvn clean verify'
// 或者,如果report目标绑定到test阶段,`mvn clean test` 也可以
// sh 'mvn clean test'
}
}
stage('SonarQube Analysis') {
steps {
// SonarQube扫描器将自动读取pom.xml中定义的sonar.*属性
// 确保不要在命令行中覆盖pom.xml中的sonar.coverage.jacoco.xmlReportPaths
withSonarQubeEnv('Your SonarQube Server') { // 'Your SonarQube Server' 是Jenkins中配置的SonarQube服务器名称
sh 'mvn sonar:sonar'
// 如果pom.xml中未定义sonar.coverage.jacoco.xmlReportPaths,则可以在此处指定
// sh 'mvn sonar:sonar -Dsonar.coverage.jacoco.xmlReportPaths=target/jacoco_report/jacoco.xml'
}
}
}
}
}注意事项:
- mvn clean verify 命令通常比 mvn clean test 更为完整,因为它会执行Maven的整个生命周期,包括 prepare-agent (通常绑定到 validate 阶段) 和 report (绑定到 test 或 verify 阶段)。
- withSonarQubeEnv 步骤确保SonarQube环境变量被正确设置。
- 如果 pom.xml 中已正确配置 sonar.coverage.jacoco.xmlReportPaths,则 mvn sonar:sonar 命令会自动读取该属性,无需在命令行中重复 -D 参数,以避免潜在的冲突。
4. 验证与故障排除
完成上述配置后,执行Jenkins流水线。
- 检查Maven构建日志: 确保没有 Skipping JaCoCo execution due to missing execution data file 警告。
-
检查项目 target 目录:
- 在 target/coverage-reports/ 目录下,应该能找到 jacoco-ut.exec 文件。
- 在 target/jacoco_report/ 目录下,应该能找到 jacoco.xml 文件。
- 在 target/surefire-reports/ 目录下,应该能找到单元测试的XML报告。
- 检查Sonarqube分析日志: 在Jenkins的SonarQube分析步骤中,查看日志输出,确认Sonarqube扫描器是否成功读取了JaCoCo XML报告。日志中应包含类似 INFO: Sensor JaCoCo XML Report Sensor [jacoco] (done) ... 的信息,并且会列出它处理的XML报告路径。
- 查看Sonarqube界面: 登录Sonarqube,检查项目的代码覆盖率是否已正确显示。
如果仍然遇到问题,请仔细核对所有路径和文件名是否完全一致,并确保Maven插件的版本兼容。
5. 总结
在Sonarqube中实现JaCoCo代码覆盖率的正确显示,核心在于JaCoCo、Surefire插件以及Sonarqube扫描器之间关于报告文件路径和格式的配置一致性。通过在Maven pom.xml 中统一









