Skip to content

覆盖率 = 测试跑到了多少代码。它不能证明"代码都对",但能告诉你哪里没测到——是找测试盲区的雷达。这篇讲 JaCoCo(Java 最常用的覆盖率工具)怎么配置、报告怎么看、覆盖率怎么提。

验证说明:本文示例已用 Maven 项目实跑验证(IDEA 内置 Maven + jacoco-maven-plugin 0.8.12)——文章里的 PriceService + 参数化测试跑完,指令/分支/行覆盖率均 100%,check 门禁通过,报告生成于 target/site/jacoco/index.html

一、覆盖率是什么

覆盖类型含义通俗理解
行覆盖(Line)多少行代码被执行过每行代码跑没跑到
分支覆盖(Branch)if/else 的每个分支是否都走过判断的"是/否"都测了吗
方法覆盖(Method)多少方法被调用过方法进没进过
类覆盖(Class)多少类被加载过类测没测到

关键行覆盖 ≠ 分支覆盖——if (a && b) 这一行跑了,但 a=false 的分支可能没测。重点看分支覆盖

二、JaCoCo 配置(Maven)

pom.xml 加插件(test 阶段自动生成覆盖率报告):

xml
<build>
    <plugins>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.12</version>
            <executions>
                <!-- 测试前埋点 -->
                <execution>
                    <goals><goal>prepare-agent</goal></goals>
                </execution>
                <!-- 测试后生成报告 -->
                <execution>
                    <id>report</id>
                    <phase>test</phase>
                    <goals><goal>report</goal></goals>
                </execution>
                <!-- 覆盖率不达标构建失败(质量门禁) -->
                <execution>
                    <id>check</id>
                    <phase>verify</phase>
                    <goals><goal>check</goal></goals>
                    <configuration>
                        <rules>
                            <rule>
                                <element>BUNDLE</element>
                                <limits>
                                    <limit>
                                        <counter>LINE</counter>
                                        <value>COVEREDRATIO</value>
                                        <minimum>0.90</minimum>   <!-- 行覆盖 90% -->
                                    </limit>
                                    <limit>
                                        <counter>BRANCH</counter>
                                        <value>COVEREDRATIO</value>
                                        <minimum>0.80</minimum>   <!-- 分支覆盖 80% -->
                                    </limit>
                                </limits>
                            </rule>
                        </rules>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
bash
mvn test          # 跑测试 + 生成报告
# 报告在 target/site/jacoco/index.html

实测结果(本文示例项目):mvn test verifyjacoco.csv 显示 PriceService 行覆盖 5/5、分支 6/6、指令 28/28——全部 100%check 门禁(行≥90%、分支≥80%)通过。

check 规则让覆盖率不达标构建失败——把覆盖率变成"质量门禁"(低于 90% 不让合并代码,和 CI 流水线配合见《CI/CD 快速入门》)。

三、报告怎么看

打开 target/site/jacoco/index.html

颜色含义
🟢 绿已覆盖
🔴 红未覆盖(重点看这里
🟡 黄部分覆盖

怎么看

  1. 先看包/类列表,找红色(未测的类)
  2. 点进类,红色行 = 没执行的代码,黄色菱形 = if 只测了一个分支
  3. 重点补:核心业务逻辑(Service 层)、异常分支(catch)、边界条件(if 的分支)

四、覆盖率怎么提(实操手法)

java
// 假设被测方法
public class PriceService {
    public double calc(double price, int discountType) {
        if (discountType == 1) return price * 0.9;        // 分支 1
        if (discountType == 2) return price * 0.8;        // 分支 2
        if (price < 0) throw new IllegalArgumentException(); // 异常分支
        return price;                                      // 默认分支
    }
}

用参数化测试一次覆盖全部分支(《JUnit 5 进阶》的 @CsvSource 正是干这个的):

java
@ParameterizedTest
@CsvSource({
    "100, 1, 90",     // 分支 1
    "100, 2, 80",     // 分支 2
    "-1, 0, EXCEPTION", // 异常分支
    "100, 0, 100"     // 默认分支
})
void 折扣计算(double price, int type, double expected) { ... }

提高覆盖率的套路(按性价比排序):

  1. 分支全覆盖:if/else 每个分支 + 异常分支都测(参数化测试最省力)
  2. 边界值:0、负数、最大值、空值、null
  3. 先测核心业务(Service),再补工具类
  4. 别为覆盖率写废测试:只断言不验证逻辑的测试是"注水"——覆盖率数字上去了,但没实际价值(反而误导)

五、常见坑

  1. 只追行覆盖:行覆盖 90% 但分支 50%——if 只测了一半分支(重点看 BRANCH)
  2. 给 getter/setter 凑覆盖率:没意义,JaCoCo 可配置排除(excludes
  3. 覆盖率 100% 的幻觉:覆盖 ≠ 正确,assertEquals(1, 1) 也算覆盖——覆盖率 + 断言质量一起看
  4. CI 里没配 check:本地测了,CI 不强制,覆盖率慢慢掉——在流水线加 check 规则
xml
<!-- 排除样板代码(getter/setter/配置类)不参与统计 -->
<configuration>
    <excludes>
        <exclude>**/dto/**</exclude>
        <exclude>**/config/**</exclude>
        <exclude>**/*Application.class</exclude>
    </excludes>
</configuration>

小结

  • 覆盖率 = 测试盲区雷达:行覆盖 + 分支覆盖一起看
  • JaCoCo:prepare-agent(埋点)+ report(报告)+ check(门禁)
  • 报告红绿看盲区,黄色菱形 = 分支没测全
  • 提高覆盖率:参数化测试覆盖分支 + 边界值 + 先测核心业务
  • 别注水:覆盖率数字 + 断言质量一起看(配 CI check 防止回退)