测试覆盖率

2012年4月17日

我经常听到人们问他们应该追求什么样的测试覆盖率(也称为代码覆盖率),或者自豪地宣布他们的覆盖率水平。这些说法都错过了重点。测试覆盖率是查找代码库中未测试部分的有用工具。测试覆盖率作为衡量测试质量的数值指标毫无用处。

让我们先看看第二个说法。我听说过一些地方会说“覆盖率低于 87% 无法投入生产”。我听说过一些人说应该使用 TDD 并必须达到 100% 的覆盖率。一位智者曾经说过

我期望高水平的覆盖率。有时经理会要求这样做。两者之间存在细微差别。

-- Brian Marick

如果你将某个覆盖率水平作为目标,人们就会努力实现它。问题是,用低质量的测试很容易达到高覆盖率。最荒谬的例子是 断言免费测试。但即使没有这种测试,你也会得到很多测试,这些测试寻找很少出错的东西,让你分心,无法测试真正重要的事情。

与大多数编程方面一样,测试需要思考。TDD 是一种非常有用但绝非足够的工具,可以帮助你获得良好的测试。如果你在认真地进行测试,我预计覆盖率将在 80% 或 90% 以上。如果覆盖率达到 100%,我会感到怀疑——这会让人觉得有人在编写测试以使覆盖率数字看起来很漂亮,但没有思考他们在做什么。

当然,人们关注覆盖率数字的原因是他们想知道自己是否测试了足够多。当然,低覆盖率数字(例如低于一半)是一个麻烦的信号。但高数字并不一定意味着什么,会导致 促进无知的仪表盘。测试的充分性比覆盖率所能回答的要复杂得多。我认为,如果你满足以下条件,你就进行了足够的测试

  • 你很少遇到逃逸到生产环境中的错误,并且
  • 你很少因为害怕会引起生产环境错误而犹豫不决地更改代码。

你能测试太多吗?当然可以。如果你可以在仍然有足够测试的情况下删除测试,那么你就是在测试太多。但这很难察觉。一个迹象表明你测试太多的是,你的测试速度太慢。如果代码的简单更改会导致测试的更改时间过长,那么这表明测试有问题。这可能不是因为你测试了太多东西,而是因为你的测试中存在重复。

有些人认为,如果测试运行时间过长,那么测试就太多了。我不太相信这种说法。你总是可以将速度慢的测试移到部署管道的后期阶段,甚至可以将它们从管道中移除并定期运行。这样做会减慢这些测试的反馈速度,但这只是构建时间与测试信心之间的权衡的一部分。

那么,覆盖率分析的价值是什么呢?它可以帮助你找到哪些代码部分没有被测试。 [1] 值得定期运行覆盖率工具并查看这些未测试的代码部分。你是否担心它们没有被测试?

如果你的测试套件在覆盖率可以检测到的方面很弱,那么它很可能在覆盖率无法检测到的方面也很弱。

-- Brian Marick

进一步阅读

Brian Marick 有一篇关于 代码覆盖率的误用 的精彩文章。值得阅读 Testivus 的简洁评论

笔记

1: 这里的“你”指的是编写测试的人。覆盖率对管理人员来说几乎没有价值,因为你需要具备技术背景才能理解测试是否良好,或者未覆盖的代码是否是一个问题。