You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jacoco与SonarQube代码覆盖率结果不一致问题排查

Jacoco与SonarQube代码覆盖率差异及排除规则无效问题

执行mvn clean verify时,Jacoco显示行覆盖率64%、分支覆盖率62%,但SonarQube中代码覆盖率显示为70%(截图如下):
SonarQube覆盖率截图

我未在Jacoco或Sonar中排除任何类,且两者使用同一分支。以下是pom.xml配置快照:

<jacoco.version>0.8.8</jacoco.version>
<properties-maven-plugin.version>1.1.0</properties-maven-plugin.version>
<sonar-maven-plugin.version>3.9.1.2184</sonar-maven-plugin.version>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.sources>src/main</sonar.sources>
<sonar.tests>src/test</sonar.tests>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.coverage.jacoco.xmlReportPaths>target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
<sonar.language>java</sonar.language>

    <plugin>
        <groupId>org.sonarsource.scanner.maven</groupId>
        <artifactId>sonar-maven-plugin</artifactId>
        <version>${sonar-maven-plugin.version}</version>
    </plugin>

    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco.version}</version>
        <configuration>
            <rules>
                <rule>
                    <element>BUNDLE</element>
                    <limits>
                        <limit>
                            <counter>LINE</counter>
                            <value>COVEREDRATIO</value>
                            <minimum>60%</minimum>
                        </limit>
                        <limit>
                            <counter>BRANCH</counter>
                            <value>COVEREDRATIO</value>
                            <minimum>60%</minimum>
                        </limit>
                    </limits>
                </rule>
            </rules>
        </configuration>
        <executions>
            <execution>
                <id>coverage-initialize</id>
                <goals>
                    <goal>prepare-agent</goal>
                </goals>
            </execution>
            <execution>
                <id>coverage-report</id>
                <phase>post-integration-test</phase>
                <goals>
                    <goal>report</goal>
                </goals>
            </execution>
            <execution>
                <id>coverage-check</id>
                <goals>
                    <goal>check</goal>
                </goals>
            </execution>
        </executions>
    </plugin>


 <profile>
    <id>sonar</id>
    <activation>
        <property>
            <name>env.V_TEMPLATE_TYPE</name>
            <value>CI</value>
        </property>
        <activeByDefault>false</activeByDefault>
    </activation>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>properties-maven-plugin</artifactId>
                <version>${properties-maven-plugin.version}</version>
                <executions>
                    <execution>
                        <phase>verify</phase>
                        <goals>
                            <goal>read-project-properties</goal>
                        </goals>
                        <configuration>
                            <files>
                                <file>sonar.properties</file>
                            </files>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.sonarsource.scanner.maven</groupId>
                <artifactId>sonar-maven-plugin</artifactId>
                <version>${sonar-maven-plugin.version}</version>
                <executions>
                    <execution>
                        <phase>verify</phase>
                        <goals>
                            <goal>sonar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

另外,添加排除规则时,Sonar的结果会受影响,但Jacoco的结果无变化。我尝试在以下代码的多个位置添加排除规则(认为最合理的位置是</limits>和</rule>之间),但完全无效:

<configuration>
    <rules>
        <rule>
            <element>BUNDLE</element>
            <limits>
                <limit>
                    <counter>LINE</counter>
                    <value>COVEREDRATIO</value>
                    <minimum>70%</minimum>
                </limit>
                <limit>
                    <counter>BRANCH</counter>
                    <value>COVEREDRATIO</value>
                    <minimum>70%</minimum>
                </limit>
            </limits>
        </rule>
    </rules>
</configuration>

我还配置了用于GitHub与Sonar集成的sonar.properties文件(Sonar扫描仍在pom.xml中配置),内容如下:

sonar.projectKey=
sonar.projectName=
sonar.host.url=
sonar.login=
sonar.exclusions=OPTIONAL

问题解答

一、Jacoco与SonarQube覆盖率差异的原因

  1. 统计范围不同
    SonarQube默认会忽略部分代码,比如:
  • Lombok自动生成的getter/setter、构造函数
  • 抽象方法、接口方法
  • 静态初始化块
  • 无实际逻辑的空方法

而Jacoco会将这些代码纳入统计,导致Jacoco的覆盖率数值更低。

  1. 报告生成时机差异
    你的Jacoco报告在post-integration-test阶段生成,但SonarQube在verify阶段扫描。如果单元测试和集成测试的执行范围、顺序有差异,可能导致SonarQube读取的覆盖率数据和Jacoco的统计范围不一致。

  2. SonarQube的覆盖率过滤逻辑
    SonarQube会自动过滤标记为“生成代码”的未覆盖行,而Jacoco不会做这个处理。另外,SonarQube可能合并多阶段测试的覆盖率数据,若Jacoco报告只包含部分测试阶段结果,就会出现数值偏差。

  3. 版本兼容性问题
    你使用的Sonar Maven插件(3.9.1.2184)和Jacoco(0.8.8)版本可能存在兼容性问题,导致SonarQube解析Jacoco报告时出现偏差。建议升级Sonar Maven插件到4.0+版本,同时确保Jacoco版本与之匹配。

二、Jacoco排除规则无效的解决办法

你之前在<rules>标签里加排除规则是错误的——<rules>仅用于设置覆盖率阈值,不是排除类的配置项。正确的排除配置应该放在<configuration>下的<excludes>标签中,示例如下:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>${jacoco.version}</version>
    <configuration>
        <!-- 排除不需要统计的类 -->
        <excludes>
            <exclude>com/example/dto/**/*</exclude>
            <exclude>com/example/entity/**/*</exclude>
            <exclude>com/example/constants/**/*</exclude>
        </excludes>
        <rules>
            <rule>
                <element>BUNDLE</element>
                <limits>
                    <limit>
                        <counter>LINE</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>70%</minimum>
                    </limit>
                    <limit>
                        <counter>BRANCH</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>70%</minimum>
                    </limit>
                </limits>
            </rule>
        </rules>
    </configuration>
    <!-- 执行配置保持不变 -->
</plugin>

若要让SonarQube和Jacoco的统计范围一致,需要同时在Sonar配置(pom.xml或sonar.properties)中设置sonar.exclusions,确保两者排除规则匹配。


内容的提问来源于stack exchange,提问作者djasyfuj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:52:25