看标题就知道这篇文章很有意思,作为一个之前专注过做代码覆盖率平台的人,这个观点一直模模糊糊是存在于我的心里的,不过从来没有这么直截了当的说出来,这篇文章的作者有理有据,值得一看。原文在这里: https://drpicox.medium.com/confirmed-code-coverage-is-a-useless-management-metric-35afa05e8549,我只做了一些翻译。
有一种强烈的信念,即代码覆盖率是衡量软件产品质量的重要指标,这个信念多年来一直被技术领导者们毫无疑问地共享。从表面上看,这个理论似乎很有道理:测试越彻底,代码覆盖率越高,因此我们的软件应该更加健壮和无错误。这个观念已经深深植入我们的思维中。但是,如果我能证明代码覆盖率从根本上是错误的呢?如果我能向你展示一个如此简单的想法,让你对此毫无疑问?所以,请做好准备,做好心理准备。
鉴于本文仅展示了哪些指标不适用于管理(尽管对开发人员非常有用),但并未说明应该遵循哪些指标,因此我最近写了一篇后续文章,解释了应该使用哪四个基本指标以及为什么要这样做,这些观点都有科学依据
The Code Coverage 代码覆盖率
代码覆盖率,简单来说,是衡量你的代码有多少被测试所“触及”或“覆盖”的一种度量。我们假设在我们的产品中有测试,并且我们至少在每次发布之前运行这些测试。当这些测试执行时,它们会对产品进行操作,从而使代码执行。很快,我们意识到如果我们追踪哪些代码被测试执行,我们就可以开始衡量有多少代码被执行了。我们将执行的代码与产品中的总代码量的比例称为“代码覆盖率”。
code coverage = executed code by tests / size of the code
这是一个非常简单的度量标准。如果我们有 100 行代码,但测试只执行了其中的 75 行,那么我们的代码覆盖率为 75%。
很快我们意识到了更重要的事情。如果代码覆盖率不是 100%,那就意味着我们的测试没有执行到某些代码,换句话说:我们有未经测试的代码!
因此,拥有未经测试的代码是危险的,因为它可能包含错误。此外,它还可能包含业务关键功能,如果我们触碰到该代码,我们可能会丧失这些功能。
所以,拥有高代码覆盖率是必须的。
代码覆盖率的谬论
但是,现在我们面临一个谬论:我们知道揭示代码意味着我们的测试遗漏了重要的情况,但反过来并不成立。
例如,在之前的例子中,我们的代码覆盖率为 75%。换句话说,这个指标表示有 25%的代码行没有被任何测试执行过,这明确指出了一个风险区域。我们可以确定地说,这 25%的代码库没有经过任何测试验证,因此可能成为问题和维护困难的滋生地。
然而,这就是我们冒险陷入谬误的时候:虽然我们可以自信地说未经测试的代码隐藏了潜在的错误和对未来发展的阻碍,但我们可能相信相反的情况是真实的。我们可能相信代码覆盖意味着它有更少的错误和更少的维护问题。但是,这只是一个直觉,甚至可能看起来很合乎逻辑,但事实证明这并不正确。
事实是,我们可以实现 100%的代码覆盖率,但代码仍然可能存在大量的错误,并且难以维护。
一个基本的例子
想象一个简单的函数,它计算两个数字的和:
function addition(a, b) {
return a + b;
}
哪个是能够覆盖 100%的最简单的测试?只需添加一个附加项即可使所有代码执行:
test('the addition function', () => {
addition(3, 4);
});
这个测试覆盖了 100%的代码。然而,它是无用的。为什么呢?如果我们将加法的实现改为这样一个:
function addition(a, b) {
return a - b;
}
测试仍然通过!