What is a reasonable code coverage % for unit tests (and why)?如果您要为单元测试规定最低百分比的代码覆盖率,即使是作为提交到存储库的需求,那它会是什么? 请解释你是如何得出答案的(因为如果你所做的只是选择一个数字,那么我就可以自己完成这一切;) 阿尔贝托·萨沃亚的这篇散文恰恰回答了这个问题(以一种非常有趣的方式!): http://www.artima.com/forums/flat.jsp?论坛=106&thread=204677
如果100%覆盖率是您的目标(而不是100%测试所有特性),那么代码覆盖率是一个误导性指标。
因此,请相信您自己或您的开发人员是彻底的,并通过他们的代码覆盖每一条路径。实事求是,不要追求神奇的100%覆盖率。如果你的代码是TDD的,你应该得到90%以上的覆盖率作为奖励。使用代码覆盖率突出显示您错过的代码块(如果是TDD,则不应该发生)。因为编写代码只是为了通过测试。没有合作伙伴测试,任何代码都不能存在。) 代码覆盖率很好,但功能覆盖率更好。我不相信能覆盖我写的每一行。但我确实相信,要为我想要提供的所有功能编写100%的测试覆盖率(即使对于我自己附带的、在会议期间没有讨论过的特别酷的功能)。 我不在乎我是否会有测试中没有涉及的代码,但我关心我是否会重构我的代码并最终得到不同的行为。因此,100%的功能覆盖率是我唯一的目标。 公认的答案很有意义——没有一个数字可以作为每个项目的标准。有些项目不需要这样的标准。我认为,在我看来,接受的答案不足以说明一个人如何为一个给定的项目做出决定。好的。 我想试试看。我不是测试工程方面的专家,很高兴看到一个更明智的答案。好的。何时设置代码覆盖率要求 首先,你为什么要把这样一个标准强加在第一位?一般来说,当你想在你的过程中引入经验的信心时。我所说的"经验信心"是什么意思?好吧,真正的目标正确性。对于大多数软件,我们不可能在所有输入中都知道这一点,所以我们决定说代码是经过良好测试的。这一点更为清楚,但仍然是一个主观标准:无论你是否达到了这一标准,它都会一直公开辩论。这些辩论是有用的,应该发生,但它们也暴露出不确定性。好的。 代码覆盖率是一个客观的度量:一旦您看到覆盖率报告,就不会对是否满足标准产生歧义。它证明了正确性吗?一点也不,但它与测试代码的好坏有着明确的关系,这反过来又是我们增强对其正确性信心的最佳方法。代码覆盖率是我们所关心的不可测量的特性的可测量的近似值。好的。 一些特殊情况下,有经验标准可以增加价值:好的。
使用哪些指标 代码覆盖率不是一个单一的度量标准;有几种不同的度量覆盖率的方法。您可以根据哪个标准来设置标准,这取决于您使用该标准来满足什么。好的。 我将使用两个常用度量作为示例,说明何时可以使用它们来设置标准:好的。
还有许多其他指标(行覆盖率类似于语句覆盖率,但对于多行语句会产生不同的数值结果;条件覆盖率和路径覆盖率类似于分支覆盖率,但反映了可能遇到的程序执行排列的更详细视图)。好的。需要多少百分比 最后,回到最初的问题:如果您设置了代码覆盖率标准,那么这个数字应该是什么?好的。 希望在这一点上我们可以清楚地看到,我们要讨论的是一个近似值,所以我们选择的任何数字都是固有的近似值。好的。 一些可以选择的数字:好的。
我在实践中还没有看到低于80%的数字,很难想象一个可以设定它们的情况。这些标准的作用是增加对正确性的信心,低于80%的数字并不是特别令人鼓舞的信心。(是的,这是主观的,但同样的,我们的想法是在设定标准时做出一次主观的选择,然后进行客观的测量。)好的。其他音符 上面假设正确性是目标。代码覆盖率只是信息;它可能与其他目标相关。例如,如果您关心可维护性,那么您可能关心松耦合,松耦合可以通过可测试性来证明,而松耦合又可以通过代码覆盖率来度量(以某些方式)。因此,您的代码覆盖率标准也为近似"可维护性"的质量提供了经验基础。好的。好啊。 我最喜欢的代码覆盖率是100%,带星号。星号之所以出现,是因为我更喜欢使用允许我将某些行标记为"不算数"的行的工具。如果我已经覆盖了100%的"计数"行,我就完成了。 基本流程是: 这样一来,如果我和我的合作者在未来添加新代码或更改测试,就有一条很好的线告诉我们是否遗漏了一些重要的东西——覆盖率下降到100%以下。但是,它还提供了处理不同测试优先级的灵活性。 我想分享一下关于测试覆盖率的另一个轶事。 我们有一个巨大的项目,在Twitter上,我注意到,通过700个单元测试,我们只有20%的代码覆盖率。 斯科特·汉塞尔曼用智慧的话语回答:
同样,它回到了我关于代码覆盖率答案的测试中。你应该在锅里放多少米?这要看情况而定。 对于一个设计良好的系统,从一开始就由单元测试驱动开发,我会说85%是一个相当低的数字。设计为可测试的小类不应该比这更难覆盖。好的。 这个问题很容易被忽略,比如:好的。
是的,但是关于代码覆盖率还有一些重要的问题需要考虑。根据我的经验,这个度量标准在正确使用时实际上非常有用。尽管如此,我还没有看到所有的系统,我相信在很多系统中,很难看到代码覆盖率分析增加了任何实际价值。代码看起来如此不同,可用测试框架的范围也可能不同。好的。 另外,我的推理主要涉及相当短的测试反馈循环。对于我正在开发的产品,最短的反馈循环是相当灵活的,涵盖了从类测试到进程间信令的所有内容。测试可交付的子产品通常需要5分钟,对于如此短的反馈循环,确实可以使用测试结果(特别是我们在这里看到的代码覆盖率度量)来拒绝或接受存储库中的提交。好的。 当使用代码覆盖率度量时,您不应该只拥有必须满足的固定(任意)百分比。在我看来,这样做并不能给您代码覆盖率分析带来真正的好处。相反,定义以下指标:好的。
只有当我们不在LWM之上,也不在HWM之下时,才能添加新代码。换言之,不允许降低代码覆盖率,应该覆盖新代码。注意我说的应该和不必(解释如下)。好的。 但这难道不意味着你将不可能清除那些你已经不再使用的经过充分测试的旧垃圾吗?是的,这就是为什么你必须务实对待这些事情。有些情况下,规则必须被打破,但对于您典型的日常集成,我的经验是,这些指标非常有用。它们给出了以下两个含义。好的。
同样,如果反馈循环太长,那么在集成过程中设置类似的东西可能是完全不现实的。好的。 我还想提到代码覆盖度量的两个更一般的好处。好的。
为了完整性,是否定的。好的。
好啊。 如果这是一个完美的世界,100%的代码将被单元测试覆盖。然而,由于这不是一个完美的世界,这是一个你有时间做什么的问题。因此,我建议少关注特定的百分比,多关注关键领域。如果您的代码写得很好(或者至少是一个合理的复制品),那么在API暴露于其他代码的地方应该有几个关键点。 将您的测试工作集中在这些API上。确保API 1)有良好的文档记录,2)编写了与文档匹配的测试用例。如果预期的结果与文档不匹配,那么您的代码、文档或测试用例中都有一个bug。所有这些都是很好的审查。 祝你好运! 许多商店不重视测试,所以如果你高于零,至少会有一些价值的增值-所以可以说,非零并不坏,因为许多商店仍然是零。 在.NET世界里,人们经常引用80%的话作为理由。但他们在解决方案层面上这样说。我更喜欢在项目级别进行度量:如果您有Selenium等或手动测试,30%对于UI项目可能是好的,20%对于数据层项目可能是好的,但是如果不是完全必要的话,95%以上对于业务规则层可能是可以实现的。因此,总体覆盖率可能是60%,但关键业务逻辑可能要高得多。 我也听说过:追求100%,你会达到80%;但是追求80%,你会达到40%。 底线:应用80:20规则,让你的应用程序的错误计数指导你。 85%是登记标准的良好起点。 我可能会根据测试子系统/组件的关键性,选择各种更高的条作为运输标准。 当我认为我的代码没有经过足够的单元测试,并且我不确定下一步要测试什么时,我使用覆盖率来帮助我决定下一步要测试什么。 如果我在单元测试中增加覆盖率-我知道这个单元测试有价值。 这适用于未涵盖、50%涵盖或97%涵盖的代码。 代码覆盖率只是另一个度量标准。就其本身而言,这可能是非常误导性的(参见www.thoughtworks.com/insights/blog/are test coverage metrics overrated)。因此,您的目标不应该是实现100%的代码覆盖率,而是确保测试应用程序的所有相关场景。 我使用cobertura,不管百分比是多少,我建议保持cobertura检查任务中的值是最新的。至少,将totallinerate和totalbrancharate提高到略低于当前覆盖率,但不要降低这些值。还将Ant构建失败属性与此任务联系起来。如果构建由于覆盖率不足而失败,那么您知道有人添加了代码,但没有对其进行测试。例子:
如果你已经做了相当长的时间的单元测试,我认为没有理由不接近95%。但是,至少,我一直在用80%的速度工作,即使是刚开始测试的时候。 这个数字应该只包括项目中编写的代码(不包括框架、插件等),甚至可能排除完全由对外部代码的调用编写的代码组成的某些类。这种呼吁应该被嘲弄。 一般来说,从我读过的几篇工程卓越最佳实践论文中,80%的单元测试中的新代码是产生最佳回报的关键。超过这个CC%所产生的力的缺陷量会更低。这是许多大公司采用的最佳实践。 不幸的是,这些结果大多是公司内部的,因此没有公开文献可供参考。 代码覆盖率很高,但前提是您从中获得的好处大于实现它的成本/努力。 我们已经按照80%的标准工作了一段时间,但是我们刚刚决定放弃这个标准,转而更加关注我们的测试。专注于复杂的业务逻辑等, 这个决定是由于我们花在追逐代码覆盖率和维护现有单元测试上的时间越来越多而做出的。我们觉得我们已经到了这样的地步:我们从代码覆盖中获得的好处被认为比我们为实现它所付出的努力要少。 我对这个难题的答案是,你可以测试的代码有100%的行覆盖率,不能测试的代码有0%的行覆盖率。 我在python中的当前实践是将.py模块分为两个文件夹:app1/和app2/,当运行单元测试时,计算这两个文件夹的覆盖率,并目视检查(我必须在某一天自动执行此操作)app1的覆盖率为100%,app2的覆盖率为0%。 当/如果我发现这些数字与标准不符,我会调查并修改代码的设计,使覆盖范围符合标准。 这意味着我可以建议实现100%的库代码行覆盖率。 我偶尔也会查看app2/以查看是否可以在那里测试任何代码,如果可以,我可以将其移动到app1中。/ 现在,我不太担心总覆盖率,因为根据项目的大小,总覆盖率可能会有很大的变化,但一般来说,我看到的覆盖率是70%到90%以上。 使用python,我应该能够设计一个烟雾测试,它可以在测量覆盖率的同时自动运行我的应用程序,并且在将烟雾测试与UnitTest数字结合时,有望获得100%的增长。 从另一个角度来看覆盖率:写得好、控制流清晰的代码最容易覆盖、最容易读取,而且通常代码的错误最少。通过在头脑中编写清晰和可覆盖的代码,以及通过与代码并行编写单元测试,可以获得最佳的imho结果。 在我看来,答案是"这取决于你有多少时间"。我试图达到100%,但如果我没有得到它的时间,我不会大惊小怪。 当我编写单元测试时,与开发生产代码时所戴的帽子相比,我戴的帽子不同。我想一想被测试的代码声称要做什么,以及可能破坏它的情况是什么。 我通常遵循以下标准或规则: 单元测试应该是一种文档形式,说明我的代码的预期行为是什么,即给定特定输入的预期输出,以及客户端可能希望捕获的异常(我的代码的用户应该知道什么?) 单元测试应该帮助我发现可能还没有想到的假设条件。(如何使我的代码稳定和健壮?) 如果这两条规则不能产生100%的覆盖率,那就这样吧。但一旦有时间,我就分析未发现的块和行,并确定是否还有没有单元测试的测试用例,或者是否需要重构代码以消除不必要的代码。 我更喜欢使用BDD,它使用自动验收测试、可能的其他集成测试和单元测试的组合。对我来说,问题是自动化测试套件作为一个整体的目标覆盖范围应该是什么。 除此之外,答案取决于您的方法、语言、测试和覆盖工具。在Ruby或Python中进行TDD时,不难保持100%的覆盖率,这是值得的。100%覆盖比90%左右的覆盖更容易管理。也就是说,当覆盖率缺口出现时(并且在做TDD井时,覆盖率缺口很少,而且通常值得你花时间),要比管理一个覆盖率缺口列表要容易得多,因为你总是有未发现代码的背景,所以你没有找到覆盖率缺口,并且错过覆盖率回归。 答案还取决于项目的历史。从一开始,我就发现上面的内容在以这种方式管理的项目中是可行的。我已经大大提高了大型遗留项目的覆盖率,这是值得的,但我从来没有发现回到过去填补每个覆盖率差距是可行的,因为旧的未测试代码还没有被很好地理解,不能正确、快速地做到这一点。 看看crap4j。这是一种比直接代码覆盖稍微复杂的方法。它将代码覆盖率度量与复杂性度量相结合,然后向您展示当前未测试的复杂代码。 我认为最重要的是了解覆盖率随时间的变化趋势,并了解趋势变化的原因。你认为趋势的变化是好是坏取决于你对原因的分析。 我认为正确的代码覆盖率的最佳症状是,单元测试帮助修复的具体问题的数量与您创建的单元测试代码的大小相当。 这必须取决于您所处的应用程序开发生命周期的哪个阶段。 如果你已经开发了一段时间,已经实现了很多代码,现在才意识到你需要考虑代码覆盖率,那么你必须检查你当前的覆盖率(如果存在的话),然后使用这个基线来设置每个冲刺的里程碑(或者冲刺期间的平均增长),这意味着接受代码DEB在继续提供最终用户价值的同时(至少在我的经验中,如果您增加了测试覆盖率,而最终用户看不到新特性,他们一点也不在乎)。 根据你的领域,以95%的比例拍摄是不合理的,但我不得不说,平均而言,你会看到85%到90%的平均情况。 根据代码的关键性,75%-85%是一个很好的经验法则。运输规范的测试肯定要比内部设施等更彻底。 简短回答:60-80% 长回答:我认为这完全取决于你的项目的性质。我通常一个项目一个项目地开始测试每一个实际的部分。到项目的第一个"版本"时,根据您正在进行的编程类型,您应该有一个相当好的基本百分比。此时,您可以开始"强制"最小代码覆盖率。 我认为没有这样的提单规则。应审查代码,特别注意关键细节。但是,如果还没有测试过,它就有一个bug! 这很大程度上取决于您的应用程序。例如,一些应用程序主要由无法进行单元测试的GUI代码组成。 几天前我们的目标是大于80%,但是在我们使用了大量生成的代码之后,我们不关心%的年龄,而是让审阅者对所需的覆盖率进行调用。 根据testivus的文章,我认为答案上下文应该是第二个程序员。从实践的角度来说,我们需要争取参数/目标。我认为,通过分析我们拥有的体系结构、功能(用户案例)的代码,然后提出一个数字,可以在敏捷过程中"测试"这一点。根据我在电信领域的经验,我认为60%是一个很好的检查值。 |