一、覆盖率基础:从“测没测过”到“测得好不好”

大家好,我是你们这门课的老朋友。

今天咱们聊聊覆盖率。说实话,我见过不少团队,测试用例写了一堆,跑得也挺欢,但一问“你测全了吗?”——没人能答上来。这就是典型的“黑盒测试,心里没底”。

覆盖率,说白了就是一把尺子。它告诉你:你的测试到底触碰了哪些代码,哪些地方还在“裸奔”。

1.1 什么是覆盖率?

覆盖率,全称是“代码覆盖率”。它衡量的是:在测试执行过程中,你的代码被“执行”到的比例。

举个例子。你写了一个函数,里面有10行代码。你的测试用例只跑过了其中6行。那行覆盖率就是60%。

嗯,这里要注意:覆盖率不是万能的。它只能告诉你“哪些代码被执行了”,但没法告诉你“这些代码执行得对不对”。

我个人习惯把覆盖率看作“测试的体检报告”。它不治病,但能帮你找到病灶。

核心定义:覆盖率 = (被执行的代码元素数量) / (代码元素总数量) × 100%

1.2 为什么需要覆盖率?

你可能会问:我测试用例都跑绿了,还要覆盖率干嘛?

我在项目中遇到过这样的场景:一个模块,测试用例写了200个,全部通过。结果上线第一天就崩了。为什么?因为有一个if-else分支,200个用例全走的是true分支,false分支从来没被触发过。

覆盖率就是用来揪出这种“漏网之鱼”的。它的价值有三点:

  • 量化测试完整性:让你知道测试到底覆盖了多少代码,而不是凭感觉说“测差不多了”。
  • 发现未测试代码:哪些函数、哪些分支、哪些条件组合还没被测试到,一目了然。
  • 指导测试用例设计:覆盖率报告会告诉你“这里没测到”,你就能针对性地补用例。

避坑指南:我曾经见过一个团队,把覆盖率目标定到100%,结果测试人员为了凑数字,写了一大堆“假用例”——只执行代码,不做断言。这种覆盖率就是数字游戏,毫无意义。记住:覆盖率是手段,不是目的。

1.3 覆盖率的类型

覆盖率不是只有一种。不同的维度,看问题的角度不一样。我常用的有四种:

类型 衡量对象 通俗理解 典型工具
行覆盖率 每一行代码 这行代码跑没跑过? gcov, Istanbul
分支覆盖率 if/else、switch/case 每个分支都走过吗? JaCoCo, Cobertura
函数覆盖率 每个函数/方法 这个函数被调用过吗? lcov, gcov
条件覆盖率 布尔表达式中的子条件 每个子条件都取过true和false吗? MC/DC工具

行覆盖率

最基础的一种。它统计的是:每一行可执行代码是否被至少执行过一次。

举个例子:

int add(int a, int b) {
    int c = a + b;  // 第1行
    if (c > 10) {   // 第2行
        return c;   // 第3行
    }
    return 0;       // 第4行
}

如果测试用例只传了(5, 6),那第1、2、3行会被执行,第4行不会。行覆盖率就是 3/4 = 75%。

分支覆盖率

行覆盖率有个问题:它只看“行”,不看“逻辑”。比如上面的if语句,第2行被执行了,但分支覆盖率会问:true分支和false分支都走过吗?

如果只传(5, 6),那true分支走了,false分支没走。分支覆盖率是 1/2 = 50%。

我个人觉得,分支覆盖率比行覆盖率更有价值。因为它直接反映了逻辑路径的覆盖情况。

函数覆盖率

这个最简单。它统计的是:每个函数是否被至少调用过一次。

在大型项目中,有些工具函数可能被遗漏。函数覆盖率能帮你快速发现“僵尸代码”——那些写了但从来没被测试调用过的函数。

条件覆盖率

这个稍微复杂一点。它针对的是布尔表达式中的每个子条件。

比如:if (a > 0 && b < 10)。条件覆盖率要求:a > 0 这个子条件,既要取true也要取false;b < 10 也一样。

为什么需要这个?因为分支覆盖率只看整个表达式的真假,但可能漏掉某个子条件从来没被测试到。这在安全关键领域(比如航空、汽车)特别重要。

注意:条件覆盖率是四种类型里最难达到100%的。因为组合爆炸——一个表达式有N个子条件,就需要2^N个测试用例。我建议在实际项目中,优先保证分支覆盖率和行覆盖率,条件覆盖率只在关键模块使用。

1.4 覆盖率工具概览

工具这东西,没有最好的,只有最合适的。我按语言和场景给你梳理一下:

语言 工具 特点 我的评价
C/C++ gcov + lcov GCC自带,免费,生成HTML报告 最稳,我用了十年
Java JaCoCo 支持行、分支、方法覆盖率 集成方便,推荐
Python coverage.py 纯Python实现,支持分支 简单好用,入门首选
JavaScript Istanbul / nyc 前端覆盖率标配 生态好,配合Jest用
多语言 BullseyeCoverage 商业工具,支持MC/DC 贵,但功能强大

这些工具,后面章节我们会一个一个实战。今天先有个印象就行。

1.5 知识体系总览

为了让你对本章内容有个整体把握,我画了一张图。它把覆盖率的定义、价值、类型和工具串在了一起。

代码覆盖率 定义 被执行代码 / 总代码 为什么需要 量化·发现·指导 类型 行·分支·函数·条件 工具概览 gcov·JaCoCo·Istanbul 行覆盖率 分支覆盖率 函数覆盖率 条件覆盖率 覆盖率 = 测试的“体检报告”,帮你找到代码中的盲区

这张图把本章的核心逻辑串起来了。你记住一句话就行:覆盖率是测试的体检报告,帮你找到代码中的盲区。

可可精品资料库