2. 测试覆盖率类型:行覆盖率、分支覆盖率、条件覆盖率、路径覆盖率、MC/DC覆盖率

聊到测试覆盖率,很多人第一反应就是「代码跑了多少行」。嗯,这没错,但远远不够。我在实际项目中见过太多次了——行覆盖率100%,上线照样出事故。为什么?因为你没覆盖到真正的逻辑组合。

这一节,我把五种常用的覆盖率类型掰开揉碎讲清楚。每种我都会说说它的适用场景,以及我踩过的坑。

2.1 行覆盖率(Line Coverage)

行覆盖率是最基础的指标。说白了,就是看你的测试用例执行了多少行代码。

计算公式: 已执行行数 / 总可执行行数 × 100%

举个例子:

if (a > 0) {
    b = 1;   // 第3行
} else {
    b = -1;  // 第5行
}
c = b * 2;   // 第7行

如果测试用例只传了 a = 5,那么第3行和第7行被执行了,第5行没执行。行覆盖率是 2/3 ≈ 66.7%。

我的经验: 行覆盖率做到80%以上算及格,90%以上算不错。但别迷信100%——我见过有人为了凑100%,写一堆无意义的测试用例,纯粹浪费机器时间。

2.2 分支覆盖率(Branch Coverage)

分支覆盖率看的是每个判断条件的真/假分支是否都被走到。它比行覆盖率更严格。

还是上面那段代码:

  • 分支1:a > 0 为真 → 走第3行
  • 分支2:a > 0 为假 → 走第5行

你需要两个测试用例:a = 5 和 a = -1,才能达到100%分支覆盖率。

注意: 行覆盖率100%不代表分支覆盖率100%。我曾经在一个项目中,行覆盖率95%,分支覆盖率只有60%——因为很多else分支根本没测到。结果上线后,某个异常分支触发了空指针异常。

2.3 条件覆盖率(Condition Coverage)

条件覆盖率更细了。它关注的是每个布尔子表达式(原子条件)的真假值。

看这个例子:

if (a > 0 && b < 10) {
    // do something
}

这里有2个原子条件:a > 0 和 b < 10。条件覆盖率要求每个原子条件至少取一次真、一次假。

测试用例 a > 0 b < 10 结果
a=5, b=3 真 真 真
a=-1, b=3 假 真 假
a=5, b=20 真 假 假

三个用例就能让两个原子条件都覆盖到真和假。但注意,条件覆盖率和分支覆盖率不是一回事——条件覆盖率100%了,分支覆盖率可能还是50%。

2.4 路径覆盖率(Path Coverage)

路径覆盖率是最「狠」的。它要求覆盖程序中所有可能的执行路径。

举个例子:

if (x > 0) {
    // 路径A
}
if (y > 0) {
    // 路径B
}

这里有4条路径:

  • 路径1:A不执行,B不执行
  • 路径2:A执行,B不执行
  • 路径3:A不执行,B执行
  • 路径4:A执行,B执行
现实问题: 路径数量会随着条件数量指数增长。10个if-else就有1024条路径。我见过一个模块有30多个条件分支——理论上要测10亿条路径,根本不可能。

所以实际项目中,路径覆盖率通常只用在关键模块,比如加密算法、协议解析这类核心逻辑。

2.5 MC/DC覆盖率(Modified Condition/Decision Coverage)

MC/DC是航空级软件(比如DO-178C标准)要求的覆盖率。它比条件覆盖率更严格,但比路径覆盖率更实用。

MC/DC的核心要求是:每个原子条件必须独立地影响整个判断的结果。

什么意思?看这个:

if (A && B) {
    // 结果
}

MC/DC要求:

  • 当B固定为真时,改变A的值,结果必须跟着变
  • 当A固定为真时,改变B的值,结果必须跟着变

测试用例组合:

A B 结果 说明
真 真 真 基准
假 真 假 A独立影响
真 假 假 B独立影响

3个用例就够,而不是条件覆盖率的4个。这就是MC/DC的巧妙之处——用最少的用例,验证每个条件的独立影响。

避坑指南: 我曾经在一个安全关键项目中,MC/DC覆盖率要求100%。一开始我们用工具自动生成用例,结果发现工具生成的用例虽然覆盖了MC/DC,但很多场景根本不符合业务逻辑。后来我手动补充了20%的用例,才真正把问题测出来。工具是辅助,脑子才是关键。

2.6 五种覆盖率的对比

我整理了一张表,方便你对比:

覆盖率类型 覆盖粒度 用例数量 适用场景 我的建议
行覆盖率 代码行 少 快速评估 别只看这个
分支覆盖率 判断分支 中等 常规项目 至少做到这个
条件覆盖率 原子条件 中等 复杂逻辑 配合分支一起用
路径覆盖率 完整路径 指数级 核心模块 只用在关键处
MC/DC覆盖率 独立影响 线性增长 安全关键 航空级必备

2.7 知识体系结构图

下面这张图,帮你理清五种覆盖率之间的关系:

测试覆盖率类型体系 测试覆盖率 行覆盖率 分支覆盖率 条件覆盖率 路径覆盖率 MC/DC覆盖率 覆盖所有执行路径 用例指数增长 覆盖真/假分支 项目最低要求 覆盖代码行执行 最基础指标 覆盖原子条件真假 配合分支使用 独立影响验证 安全关键必备 选择建议 • 日常项目:行覆盖率 + 分支覆盖率 • 复杂逻辑:增加条件覆盖率 • 安全关键:MC/DC覆盖率(DO-178C要求)

嗯,这张图把五种覆盖率的关系和选择建议都画出来了。你想想看,日常项目中,分支覆盖率做到100%已经能挡住大部分问题了。但如果你在做航空、医疗、自动驾驶这类安全关键系统,MC/DC覆盖率是绕不过去的坎。

我个人习惯是:先跑行覆盖率快速定位未执行的代码,再用分支覆盖率保证逻辑分支都走到,最后对核心模块做MC/DC。这样既高效又稳妥。

可可精品资料库