
本文旨在解决在Sonarqube中Spring Boot应用使用JaCoCo和Maven进行代码覆盖率分析时,覆盖率始终显示0%的常见问题。核心在于JaCoCo和Surefire插件之间关于执行数据文件(.exec)和报告文件(.xml)路径及格式配置不一致。通过统一Maven pom.xml中的配置,确保JaCoCo代理正确生成数据,并将其转换为Sonarqube可识别的XML报告,即可实现正确的覆盖率展示。
在使用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插件之间的配置不一致,特别是在以下几个方面:
解决此问题的关键在于确保所有相关插件和属性在 pom.xml 中保持高度一致性。
首先,在 pom.xml 的 <properties> 块中,定义Sonarqube扫描器所需的报告路径。这些路径将指导Sonarqube在哪里查找单元测试报告和JaCoCo生成的代码覆盖率XML报告。
<properties>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.0</maven-jar-plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- SonarQube 单元测试报告路径 -->
<sonar.surefire.reportsPath>${basedir}/target/surefire-reports</sonar.surefire.reportsPath>
<!-- SonarQube JaCoCo XML覆盖率报告路径 -->
<sonar.coverage.jacoco.xmlReportPaths>${basedir}/target/jacoco_report/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
</properties>注意事项:
JaCoCo插件负责在测试运行期间收集代码覆盖率数据,并将其转换为XML报告。其配置通常包含两个主要执行(execution):prepare-agent 和 report。
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version> <!-- 建议使用最新稳定版本 -->
<executions>
<!-- 1. prepare-agent: 在测试执行前准备JaCoCo代理 -->
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<!-- 指定JaCoCo代理生成的二进制执行数据文件路径 -->
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
<!-- 将JaCoCo代理参数传递给Maven Surefire插件 -->
<propertyName>surefireArgLine</propertyName>
</configuration>
</execution>
<!-- 2. report: 在测试执行后生成XML报告 -->
<execution>
<id>report</id>
<phase>test</phase> <!-- 绑定到test阶段,确保在单元测试后执行 -->
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- 指定要读取的二进制执行数据文件,必须与prepare-agent的destFile一致 -->
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
<!-- 指定XML报告的输出目录 -->
<outputDirectory>${project.build.directory}/jacoco_report</outputDirectory>
<!-- 确保生成的报告名为jacoco.xml,与sonar.coverage.jacoco.xmlReportPaths一致 -->
<outputFileNames>jacoco.xml</outputFileNames>
</configuration>
</execution>
</executions>
</plugin>注意事项:
Maven Surefire插件负责执行单元测试。它需要配置以接收并应用JaCoCo代理传递的JVM参数。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version> <!-- 建议使用最新稳定版本 -->
<configuration>
<!-- 将JaCoCo代理参数传递给JVM -->
<argLine>${surefireArgLine}</argLine>
<!-- 指定Surefire报告的输出目录,与sonar.surefire.reportsPath一致 -->
<reportsDirectory>${sonar.surefire.reportsPath}</reportsDirectory>
</configuration>
</plugin>注意事项:
在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'
}
}
}
}
}注意事项:
完成上述配置后,执行Jenkins流水线。
如果仍然遇到问题,请仔细核对所有路径和文件名是否完全一致,并确保Maven插件的版本兼容。
在Sonarqube中实现JaCoCo代码覆盖率的正确显示,核心在于JaCoCo、Surefire插件以及Sonarqube扫描器之间关于报告文件路径和格式的配置一致性。通过在Maven pom.xml 中统一 <properties> 和插件配置,特别是确保 .exec 文件的生成和读取路径一致,以及 .xml 报告的输出路径与Sonarqube期望的路径匹配,可以有效解决代码覆盖率为0%的问题。遵循本教程的步骤,将有助于构建一个健壮且准确的代码质量分析流水线。
以上就是解决Sonarqube中JaCoCo代码覆盖率显示0%的问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号