“足够”多少代码覆盖率?


37

在我们的工作中,我们开始努力提高代码覆盖率,这让我开始思考...。多少代码覆盖率足够?

什么时候达到代码覆盖率递减的地步?良好的覆盖范围与不足之间的最佳结合点是什么?它是否因您正在制作的项目类型(例如WPF,WCF,Mobile,ASP.NET)而不同(这些是我们正在编写的C#类)。


对此确实没有很好的答案。“ 大部分的单元测试覆盖率你需要什么?如何在Artima开发者论坛”提供了一些有用的建议。
RN01 2012年

Answers:


19

我们的目标是至少达到 70%。在更容易测试的事物上(例如功能数据结构),我们的目标是90%,大多数人的目标是尽可能接近100%。在与WPF相关的事情和其他很难测试的框架上,我们获得的覆盖率要低得多(只有70%)。


WPF是天生很难测试的,还是您尚未花费精力制定最佳策略来获得更好的覆盖范围?
JBRWilkinson

WPF的输入很难伪造,这是很多原因造成的。我们的测试达到了单位y或API y的水平,并且无法轻易伪造位于WPF(至少输入)“顶层”的层(使其难以使用)使测试变得困难。由于API的非GUI部分易于测试,因此这不是一个大问题,但这只是挑战,从我们的模型(或视图模型)到WPF的最后延伸。
诺亚·理查兹

1
是的,WPF值得测试。如果在编译时检查视图中的绑定,我可以接受。因此,如果更改视图绑定到的属性,至少构建会中断。但事实并非如此。这就导致我们在验收测试中使用GUI自动化,这也是很容易写的。但是至少,它使我们对系统的运行充满信心。
皮特

我喜欢这个数字(70%)。随着团队的不断壮大,我倾向于开始寻找覆盖率而非价值的测试。关于WPF的评论,我们才刚刚起步。意思是,我们并不是在构建/构造易于测试的WPF代码。模拟模型有帮助。设计代码时,请将其设计为可测试的。而且,是的,目前只有有限的示例,因此您需要考虑一下。就像大多数开发人员所处的位置一样,TDD是第一次引入他们的,只有很少的行业经验。
Jim Rush

更具体地讲,WPF是单元测试的障碍,如果出于某种原因需要更大的覆盖率,最简单的WPF类覆盖率的方法就是使用编码的UI测试/集成测试
jk。

55

我认为仅代码覆盖率是一个很差的指标。例如,很容易产生大量无用的测试来覆盖代码,但是却没有充分检查输出或不测试边缘情况。覆盖代码只是意味着它不会引发异常,并非正确。您需要质量测试-数量不是那么重要。


8
代码覆盖率应该是在自动化构建系统中执行的自动化测试的输出之一。不检查输出的测试几乎不值得拥有。低于阈值覆盖率表示没有测试/测试不足的新功能。它不应该成为打败别人的东西-但是可以肯定它可以标记未经测试的代码。
JBR威尔金森

3
我在这里第二次JBRWilkinson,尽管这不是良好代码的指标,但是代码覆盖率却可以表明缺乏测试。您的单元测试还可以通过其他方式提供其他指标,例如性能指标,这样当新版本在意外的工作负载下使服务器崩溃时,您不会突然感到惊讶。
Matthieu M.

4
我认为这是一个错误的选择。仅涉及少量代码的高质量测试对质量的总体衡量标准就很差,而涉及大量代码但并不真正检查结果的“测试”也是如此。换句话说,想象一下汽车的质量保证过程,该过程在测试前驾驶员侧轮方面非常彻底,但没有测试汽车的其他部分。这和QA流程(只是一个家伙盯着整辆车说“是的,看起来不错”)的质量保证方法一样不好。
诺亚·理查兹

38

“足够”是指您可以确信自己没有破坏任何东西的情况下可以对代码进行更改。在某些项目中,可能是10%,在其他项目中,可能是95%。

它几乎从未高达100%。但是,有时尝试获得100%的代码覆盖率可能是消除代码库中混乱的好方法。不要忘记,有两种方法可以增加代码覆盖率-编写更多测试或删除代码。如果由于难以测试而没有覆盖代码,则很有可能您可以简化或重构以使其更易于测试。如果它太晦涩难于进行测试,那么通常很有可能代码中没有其他东西正在使用它。


24
“测试,直到恐惧变成无聊”
布拉德·梅斯

2
支持有关删除代码的评论。我一直使用代码覆盖率指标(在VS中,它会突出显示未覆盖的行)。
诺亚·理查兹

伟大的报价@bemace
jayraynet,2011年

14

代码覆盖率渐近地接近100%。因此,最后5%的努力可能比它值得的付出更多,因为您开始为所花费的努力获得微乎其微的回报。


7

覆盖率是一个值得关注指标,但它不是最终目标。我已经看过(并写出了!)大量的高覆盖率代码-100%覆盖率(当然是TDD),但是:

  • 错误仍然出现
  • 设计仍然很差
  • 你真的可以杀死自己为任意覆盖目标的射击-选择战斗:p

我认为这里有一个“见证方式” 条目值得参考:)


5

大多数代码中只有20%会在80%的时间运行。除非与调用图配对以确定最需要测试的内容,否则代码覆盖率分析不是很有用。这告诉您可能的情况。您可能只针对那些极端情况提出了100个测试,这些测试不到实际代码的5%。

因此,请确保覆盖定义关键路径的20%的100%,其余的至少50%(根据调用图)。这应该使您(大约)获得70%-75%的总覆盖率,但这有所不同。

不要浪费时间试图获得超过70%的总覆盖率,同时不对关键的情况进行检查。


代码覆盖率工具不是按照定义生成调用图吗?
JBR威尔金森'01

4

使用覆盖率作为指示未测试区域的指南。了解覆盖范围未编码的原因比明智的做法是覆盖范围更广。记录短缺的原因是一种良好的纪律,可以使风险得到平衡。

有时,原因不如预期的“例如,时间用完了”,但对于早期发布可能是可以的。最好标记区域以便稍后再覆盖。

我在关键飞行软件上工作,该软件认为100%的声明覆盖率适用于非关键系统。对于更关键的系统,我们检查分支/决策覆盖范围,并使用称为MC / DC的技术,该技术有时不够严格。

我们还必须确保我们也涵盖了目标代码。

在我们认为非常高的风险与价值/成本之间取得了平衡。根据遗漏错误的风险,需要做出明智的选择。


3

当您开始考虑可能会影响运行时性能,安全性,灵活性或可维护性的更改以允许更多代码覆盖时,就该结束寻求更大代码覆盖率的追求了。

我的项目的那个点是0%,因为无法计算覆盖率而不会损害设计,而其他项目的覆盖率则高达92%。

代码覆盖率指标仅在指出您可能错过了一些测试时才有用。他们没有告诉您测试质量。


2

空间关键型软件要求100%的声明覆盖率。

首先,这没有任何意义。大家都知道,全面的测试覆盖范围并不意味着代码已经过完整测试,并且不实际测试应用程序就可以轻松获得100%的覆盖范围。

尽管如此,100%的覆盖率是一个下限:尽管100%的覆盖率不能证明没有错误,但是可以肯定的是,覆盖率较小的代码没有经过完整的测试,这对于空间关键的软件来说是完全不可接受的。


2

我非常喜欢@RevBingo的回答,因为他建议100%的努力会导致您清理或删除未使用的代码。我在其他答案中没有看到的是一种何时需要高覆盖率以及何时不需要的感觉。我开始刺了一下。我认为,像这样向图表添加详细信息比找到一个适合所有代码的测试覆盖率编号更有用。

100%

对于未连接到数据库且不返回HTML的公共API(例如java.util Collections),我认为100%的覆盖率是一个崇高的开始目标,即使您因时间或其他原因而选择90-95%约束。功能完备后,增加测试范围将比其他类型的代码审阅更详细地进行审查。如果您的API非常流行,人们将以您无法期望的方式使用它,对其进行子类化,反序列化等。您不希望他们的最初经验是发现错误或设计疏漏!

90%

对于采用数据结构并返回数据结构的业务基础结构代码,100%可能仍然是一个不错的开始目标,但是,如果此代码的公开程度不足以引起很多误用,也许85%还是可以接受的?

75%

对于接受并返回String的代码,我认为单元测试要脆弱得多,但是在许多情况下仍然有用。

50%以下

我讨厌为返回HTML的函数编写测试,因为它是如此脆弱。如果有人更改了CSS,JavaScript或您返回的HTML和英语的全部内容,这对人类最终用户毫无意义?如果您可以找到一个使用大量业务逻辑来生成少量HTML的函数,则可能值得进行测试。但是相反的情况可能根本不值得测试。

接近0%

对于某些代码,“正确”的定义是“对最终用户有意义”。您可以针对此代码执行非传统测试,例如自动语法检查或HTML验证输出。我什至设置了grep语句,以解决我们通常会在工作中遇到的一些小矛盾之处,例如在系统其余部分将其称为“登录”时说“登录”。这个人严格来说不是单元测试,而是在不期望特定输出的情况下捕获问题的有用方法。

但最终,只有人类才能判断对人类有意义的事物。单元测试无法帮助您。有时,需要几个人才能正确判断。

绝对0%

这是一个可悲的类别,我觉得不太适合写作。但是,在任何足够大的项目中,都会有很多漏洞,这些漏洞可能会占用人周的时间,却没有提供任何业务利益。

我买了一本书是因为它声称可以显示如何自动模拟数据以测试Hibernate。但是它仅测试了Hibernate HQL和SQL查询。如果必须执行大量的HQL和SQL,您实际上并没有获得Hibernate的优势。Hibernate内存数据库有一种形式,但是我还没有花时间来弄清楚如何在测试中有效地使用它。如果我运行了该程序,那么我希望对通过导航导致Hibernate运行某些查询的对象图来计算内容的任何业务逻辑进行较高的测试覆盖率(50%-100%)。我测试此代码的能力目前接近0%,这是一个问题。因此,我提高了项目其他区域的测试覆盖率,并尝试使用纯函数而不是访问数据库的函数,这主要是因为为这些函数编写测试更加容易。仍然,


1

我认为这取决于您正在测试的应用程序部分。例如,对于业务逻辑或涉及复杂数据转换的任何组件,我的目标是90%(尽可能高)的覆盖率。我经常通过测试尽可能多的代码来发现小而危险的错误。我宁愿在测试期间发现此类错误,也不要让它们在一年后出现在客户现场。同样,高代码覆盖率的好处在于,它可以防止人们过于轻易地更改工作代码,因为必须相应地调整测试。

另一方面,我认为有些组件的代码覆盖率不太合适。例如,在测试GUI时,编写一个测试以涵盖将单击按钮分配给正确的组件时单击的所有代码的测试非常耗时。我认为在这种情况下,使用传统的执行手动测试的方法会更加有效,您只需单击按钮并观察程序的行为即可(是否打开了正确的对话框窗口?是否选择了正确的工具? ?)。


0

对于使用代码覆盖率作为衡量测试套件何时具有足够覆盖率的一种措施,我没有很高的评价。

这样做的主要原因是,如果您有一个过程,首先编写一些代码,然后进行一些测试,然后查看代码覆盖率以发现错过了测试的位置,那么您的过程需要改进。如果您执行的是真正的TDD,那么您的开箱即用的代码覆盖率就是100%(诚然,我没有测试过一些琐碎的东西)。但是,如果您查看代码覆盖范围以找出要测试的内容,则可能会编写错误的测试。

因此,您可以从代码覆盖率中得出的唯一结论是,如果代码覆盖率太低,那么您将没有足够的测试。但是,如果它很高,则不能保证您具有所有正确的测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.