有关如何反驳代码覆盖率质量参数的任何工具/建议


11

现在,我知道人们会认为这个问题重复或被问过很多次,在这种情况下,我希望获得与相关问题的链接以及我的问题的答案。

我最近在代码覆盖方面与某些人意见不一致。我有一群人希望我们的团队基于100%的覆盖率并不意味着良好的质量测试以及良好的代码质量就完全放弃代码覆盖率的研究。

通过推销“代码覆盖率”可以告诉我尚未确定的内容的论点,我可以进行回退,并帮助我们专注于这些领域。

(以上已经在类似这样的其他SO问题中以类似的方式进行了讨论-https: //stackoverflow.com/questions/695811/pitfalls-of-code-coverage

这些人的论据是-然后,团队会做出反应,迅速创建质量低下的测试,从而浪费时间,同时又不增加明显的质量。

在理解他们的观点的同时,我正在寻找一种方法,通过引入更健壮的工具/框架来照顾更多的覆盖标准, 从而使代码覆盖更可靠(Functional, Statement,Decision, Branch, Condition, State, LCSAJ, path, jump path, entry/exit, Loop, Parameter Value etc)

我正在寻找的建议是将这样的代码覆盖率工具和实践/过程结合在一起使用,这可以帮助我在对建议感到满意的同时反驳此类争论。

我也欢迎根据您的经验/知识如何提出反对意见提出的任何评论/建议,因为尽管主观,但是代码覆盖率使我的团队更加意识到了代码质量和测试价值。


编辑:为了减少对我对典型代码覆盖范围弱点的理解的困惑,我想指出的是,我并不是指 Statement Coverage(或执行的代码行)工具(有很多)。实际上,这里有一篇很好的文章介绍了所有错误之处:http : //www.bullseye.com/statementCoverage.html

我不仅在寻找语句或行覆盖率,而且还在寻找多个覆盖率标准和级别。

请参阅:http : //en.wikipedia.org/wiki/Code_coverage#Coverage_criteria

这个想法是,如果一个工具可以根据多个标准告诉我们我们的覆盖范围,那么它将成为对测试质量的合理自动化评估。我绝不是要说线路覆盖率是一个很好的评估。实际上,这就是我提出这个问题的前提。


编辑:
好的,也许我对它的预测太过夸张了,但是您明白了。问题在于以统一/一致的方式在所有团队中设置流程/策略。人们普遍担心,您如何确保测试质量,如何在没有任何措施的情况下分配保证的时间。因此,我喜欢具有可测量的功能,当使用适当的流程和正确的工具进行备份时,它将使我们能够提高代码质量,同时又知道不会浪费时间在浪费性的流程上。


编辑:到目前为止,我从答案中得到了什么:

  • 代码审查应涵盖测试以确保测试质量
  • “测试优先”策略有助于避免事后写出的测试仅增加覆盖率%
  • 探索涵盖测试标准的替代工具,而不仅仅是声明/行
  • 分析覆盖的代码/发现的错误数量将有助于理解覆盖的重要性并提供更好的案例
  • 最重要的是,请信任团队的投入以做正确的事并为自己的信念而战
  • 涵盖的区块/测试数量-值得商but,但具有一定价值

感谢您迄今为止的出色回答。我真的很感激他们。此功能比具有强大功能的头脑风暴要好几个小时。


4
任何地方都没有人建议达到100%的代码覆盖率,这确实是一个愚蠢的差事。
Jimmy Hoffa 2013年

1
谢谢。我已经知道并承认这一点。人们通常会将100%的代码覆盖率与100%的声明(或行)覆盖率关联起来。也无法抗拒-吉米,他们在各处寻找您。
MickJ

3
“那么,团队会做出反应,迅速创建低质量的测试,从而浪费时间而又不增加任何重要的质量”-优秀的团队!
2013年

好的,也许我的预测太过夸张了,但是您明白了。问题在于,以统一/一致的方式在所有团队中设置流程/策略。人们普遍担心,您如何确保测试质量,如何在没有任何措施的情况下分配保证的时间。因此,我喜欢具有可测量的功能,当使用适当的流程和正确的工具进行备份时,它将使我们能够提高代码质量,同时又知道不会浪费时间在浪费性的流程上。
MickJ 2013年

1
@JimmyHoffa-空间关键型软件通常需要100%的代码覆盖率。
mouviciel

Answers:


9

以我的经验,代码覆盖范围和您所做的一样有用。如果编写涵盖所有案例的良好测试,则通过这些测试意味着您已满足要求。实际上,这就是测试驱动开发所使用的确切想法。您在代码之前编写测试,而对实现一无所知(有时这意味着另一个团队完全编写了测试)。设置这些测试是为了验证最终产品是否完成了规范所说明的所有工作,然后编写最基本的代码来通过这些测试。

显然,这里的问题是,如果您的测试不够强大,您将错过边缘情况或无法预料的问题,并编写不真正符合您的规范的代码。如果您真的打算使用测试来验证代码,那么编写良好的测试是绝对必要的,否则您实际上是在浪费时间。

我想在这里编辑答案,因为我意识到它并没有真正回答您的问题。我将在该Wiki文章中查看TDD的一些既定好处。这实际上取决于您的组织如何最好地工作,但是TDD绝对是行业中使用的东西。


+1表示编写测试首先可以提高测试质量的建议,因此将“测试优先”与“代码覆盖率”结合使用绝对有帮助。
MickJ 2013年

是的,我一直发现,如果您在开发代码后编写测试,则只会测试您知道代码将通过的事情,或者会以补充实现的方式编写测试,真的没有帮助任何人。如果您独立于代码编写测试,则将重点放在代码该做什么而不是代码做什么
Ampt入渗

谢谢@Ampt。除了使用TDD加强流程之外,是否还建议您使用任何代码覆盖率工具,以便更详尽地处理更多覆盖率准则,从而至少在一定程度上帮助验证编写的测试的质量?
MickJ 2013年

我可能对您的理解不正确,但是您是否建议使用不同的工具来告诉您不同的测试范围?根据我的经验,覆盖率工具仅监视测试的运行并记录要执行的代码行。然后,切换工具应该不会影响覆盖范围,因为执行的行数保持不变。我会警惕为同一测试提供更多覆盖率的工具。就是说,我不认为击中每一行代码都是对测试质量的良好评估,因为它是彻底的。好的测试来自好的要求。
Ampt

谢谢。您指的是Statement Coverage(或执行的代码行)。我不仅在寻找语句或行覆盖率,multiple coverage criteria而且在层次和层次上寻找更多。请参阅:en.wikipedia.org/wiki/Code_coverage#Coverage_criteriaen.wikipedia.org/wiki/Linear_Code_Sequence_and_Jump。这个想法是,如果一个工具可以根据多个标准告诉我们我们的覆盖范围,那么它将成为对测试质量的合理自动化评估。我绝不是要说线路覆盖率是一个很好的评估。实际上,这就是我提出这个问题的前提。
MickJ

6

首先,人们确实主张100%的覆盖率:

大多数开发人员认为...“ 100%声明覆盖率”足够。这是一个好的开始,但还远远不够。更好的覆盖标准ID,可以满足所谓的“ 100%分支覆盖”。

Steve McConnell,代码完成,第22章:开发人员测试。

正如您和其他人所提到的,仅就覆盖而言,代码覆盖不可能完成太多。但是,如果您无法执行一行代码,为什么要编写呢?

我建议通过收集和分析自己项目中的数据来解决争论。

为了收集数据,我个人使用以下工具:

  • JaCoCo和相关的Eclipse插件EclEmma,用于测量代码覆盖率。
  • 用于自动构建,测试和报告的Ant脚本。
  • Jenkins进行连续构建-源代码管理中的任何更改都会触发自动构建
  • 适用于Jenkins的JaCoCo插件 -捕获每个构建的覆盖率指标,并绘制趋势图。还允许定义影响项目运行状况的每个项目的覆盖范围阈值。
  • Bugzilla用于跟踪错误。

一旦有了(或类似的东西),就可以开始更仔细地查看自己的数据了:

  • 在覆盖不良的项目中发现了更多错误吗?
  • 在覆盖不良的类/方法中发现了更多错误吗?
  • 等等

我希望您的数据支持您在代码覆盖率方面的立场;那当然是我的经验。但是,如果没有,那么您的组织可能会以比您想要的低的代码覆盖率标准来取得成功。也许您的测试不是很好。该任务有望将精力集中在生产缺陷更少的软件上,而不管代码覆盖问题的解决方案如何。


我真的很喜欢这个答案。感谢工具的建议,更重要的是,我喜欢数据支持方法来证明代码覆盖范围合理的想法。尽管我倾向于让团队相信它的价值,而且无论如何也不会对此表示怀疑。到目前为止,它可能可以帮助我为我们的经验建立更坚实的案例。谢谢!
MickJ 2013年

4

这些人的观点是- 团队会做出反应,迅速创建质量低下的测试,从而浪费时间,同时又不增加明显的质量。

这是信任的问题,而不是工具

问他们为什么,如果他们真的相信该声明,他们将完全信任团队编写任何代码?


因为他们知道代码的功能是底线,所以:可以牺牲测试,文档,注释,评论等,而没有任何直接后果;尽管我同意,但这是一个不好的信号。
JeffO 2013年

好的,也许我的预测太过夸张了,但是您明白了。问题在于,以统一/一致的方式在所有团队中设置流程/策略。人们普遍担心,您如何确保测试质量,如何在没有任何措施的情况下分配保证的时间。因此,我喜欢具有可测量的功能,当使用适当的流程和正确的工具进行备份时,它将使我们能够提高代码质量,同时又知道不会浪费时间在浪费性的流程上。
MickJ 2013年

3

好的,也许我的预测太过夸张了,但是您明白了。问题在于以统一/一致的方式在所有团队中设置流程/策略。

我认为这就是问题所在。开发人员不在乎(通常是出于很好的理由)一致或全局的政策,而是希望自由地做他们认为正确的事情,而不是遵守公司政策。

除非您证明全球流程和措施具有价值并对发展的质量和速度产生积极影响,否则这是合理的。

通常的时间表:

  1. dev:嘿,看-我向我们的仪表板添加了代码覆盖率指标,不是很好吗?
  2. 经理:当然,让我们在这些目标上添加强制性目标和合规性
  3. dev:没关系,代码覆盖是愚蠢且无用的,让我们删除它

1
+1我见过如此多次,无法达成共识。我的情况虽然对话有点这样。dev:嘿,看-我向我们的仪表板添加了代码覆盖率指标,不是很好吗?经理:当然,你们认为可以提高质量的任何事情都很棒。经理老板的老板:我认为我们需要跨团队制定一个流程。我认为代码覆盖率是毫无意义的,除非我们可以从花费的成本中保证价值。
MickJ

2

以我的经验,有一些东西可以与代码覆盖率结合起来以使度量值值得:

代码审查

如果您可以将不良测试反馈给开发人员,则可以帮助限制提供这种毫无意义的覆盖范围的不良测试的数量。

错误追踪

如果您在一个模块上覆盖了很多代码,但是在该区域中仍然遇到许多/严重的错误,那么这可能表明开发人员需要改进其测试的问题。

实用主义

在非平凡的代码上进行良好的测试,没有人能达到100%。如果您是团队负责人,请查看代码覆盖率,而不要说“我们需要达到N%!” 您可以找出差距,并要求人们“提高模块X的覆盖率”来实现您的目标,而又不给人们提供游戏系统的机会。

涵盖的区块/测试数量

大多数代码覆盖率工具列出了覆盖的块与未覆盖的块。将其与实际测试的数量结合起来,可以得到一个指标,指示“广泛”测试的程度,表明不良测试或耦合设计。作为从一个Sprint到另一个Sprint的增量,此功能更为有用,但是想法是相同的-将代码覆盖率与其他指标结合起来以获取更多见解。


+1好的建议,我特别喜欢覆盖的块/测试和代码审查的数量。尽管我们已经进行了代码审查,但强调更仔细地审查测试本身的重要性将是有帮助的。
MickJ

2

这是我的2美分。

最近有许多实践受到关注,因为它们可以为软件开发带来好处。但是,一些开发人员盲目地应用了这些实践:他们深信应用一种方法就像执行一种算法一样,并且在执行了正确的步骤之后应该可以得到想要的结果。

一些例子:

  • 编写具有100%代码覆盖率的单元测试,您将获得更好的代码质量。
  • 系统地应用TDD,您将获得更好的设计。
  • 进行配对编程,您将提高代码质量并减少开发时间。

我认为上述陈述的基本问题是,人不是计算机,编写软件不像执行算法。

因此,以上语句包含一些事实,但简化了太多事情,例如:

  • 单元测试会捕获很多错误,并且代码覆盖率指示了要测试的代码部分,但是测试琐碎的事情是没有用的。例如,如果通过单击按钮打开了相应的对话框,则可以通过简单的手动测试(单击按钮)来测试将按钮事件发送到打开对话框的组件的整个逻辑:它是否可以归结为单位测试这个逻辑?
  • 尽管TDD是一个很好的设计工具,但是如果开发人员对问题域的理解不佳,它就不能很好地工作(例如,参见此著名文章)。
  • 如果两个开发人员可以一起工作,那么配对编程将很有效,否则将是一场灾难。同样,经验丰富的开发人员可能更喜欢简短地讨论最重要的问题,然后分别进行编码:花很多时间讨论他们都已经知道的许多细节可能既无聊又浪费时间。

回到代码覆盖率。

通过推销“代码覆盖率”可以告诉我尚未确定的内容的论点,我可以进行回退,并帮助我们专注于这些领域。

我认为您必须根据情况判断某个模块的100%覆盖率是否值得。

该模块执行一些非常重要且复杂的计算吗?然后,我想测试每一行代码,但还要编写有意义的单元测试(在该领域有意义的单元测试)。

该模块是否执行一些重要但简单的任务,例如单击按钮时打开帮助窗口?手动测试可能会更有效。

这些人的论据是-然后,团队会做出反应,迅速创建质量低下的测试,从而浪费时间,同时又不增加明显的质量。

我认为它们是正确的:您不能通过100%的代码覆盖率来强制执行代码质量。添加更多工具来计算覆盖率并进行统计也无济于事。相反,您应该讨论代码的哪些部分更敏感,应该进行广泛的测试,以及哪些部分不易出错(在某种意义上,无需使用单元测试就可以更轻松地发现和修复错误)。

如果您将100%的代码覆盖率推给开发人员,有些人将开始编写愚蠢的单元测试以履行其义务,而不是尝试编写明智的测试。

您如何在没有任何措施的情况下分配保证的时间

可以衡量人的智力和判断力也许是一种幻想。如果您有能干的同事并且相信他们的判断,当他们告诉您“对于此模块,增加代码覆盖率将带来的好处非常小。因此,我们不要花任何时间在它上,或者”,您可以接受。我们将获得尽可能多的覆盖,所以我们需要多花一周时间来进行明智的单元测试。”

所以(再次,这是我的2美分):不要试图找到一个过程并设置必须覆盖所有团队,所有项目和所有模块的代码覆盖率之类的参数。找到这样一个普遍的过程是一种错觉,我相信当您找到一个过程时,它将会是次优的。


没错,我已经同意了。如果您注意到我不支持100%的代码覆盖率。它涉及通过使用bettet技术,工具和流程来提高其价值。这也有助于完全理解代码覆盖标准(大多数假设这是行/语句)。为您的优秀文章+1。
MickJ 2013年

2

“团队会做出反应,迅速创建低质量的测试,从而浪费时间,同时又不增加明显的质量”

这是真正的风险,而不仅仅是理论上的风险。

单单代码超额是一个功能失调的指标。我通过艰难的方式学到了这一课。曾经,我强调了平衡度量或实践的缺失。数百个捕获和掩盖异常且没有断言的测试是一件丑陋的事情。

“建议结合使用此类代码覆盖率工具和实践/过程”

除了所有其他建议之外,还有一种可以评估测试质量的自动化技术:变异测试(http://en.wikipedia.org/wiki/Mutation_testing)。对于Java代码,PIT(http://pitest.org/)有效,并且它是我遇到的第一个实现此目的的突变测试工具。

如您所述,缺乏代码覆盖率很容易被识别为软件质量风险。我教导说代码覆盖率是软件质量的必要条件,但不足。我们必须采取平衡的计分卡方法来管理软件质量。


1

代码覆盖范围肯定不是正确的单元测试的证明,因为它们是正确的。

但是,除非他们能够提供一种证明所有单元测试都很好的方法(无论他们能提出什么好的定义),否则这实际上是一个沉默点。


2
不说话的观点往往毫无根据。(我只是喜欢那里的文字游戏-我的拼写经常被更正)。

1

我一直发现,代码覆盖范围很容易受到霍桑效应的影响。这使我问:“为什么我们根本没有任何软件指标?” 答案通常是提供对项目当前状态的一些高级了解,例如:

“我们要完成多近?”

“这个系统的质量如何?”

“这些模块有多复杂?”

las,永远不会有一个单一的指标可以告诉您项目的好坏,任何试图从单个数字中得出含义的尝试都将过于简化。虽然指标全都与数据有关,但解释它们的含义是一项更为情感/心理的任务,因此可能无法普遍应用于具有不同组成或不同领域问题的团队。

对于覆盖率,我认为它通常被用作代码质量的代理,尽管这是粗略的。真正的问题在于,它将一个非常复杂的主题归结为一个介于0到100之间的整数,这当然会被用来推动无益的工作,以实现100%的覆盖率。像鲍勃·马丁(Bob Martin)这样的人会说100%的覆盖率是唯一的严肃目标,我能理解为什么会这样,因为其他任何事情似乎都是武断的。

当然,有很多获取覆盖率的方法实际上并不能帮助我对代码库有所了解-例如,测试toString()是否有价值?不可变对象的获取器和设置器怎么办?一个团队只能在固定的时间内申请大量的时间,而这个时间似乎总是少于完成一项完美工作所需的时间,因此,在没有完善的时间表的情况下,我们必须采用近似的方法。

我发现可以用来进行良好近似的度量标准是Crap4J。现在已经不存在了,但是您可以自己轻松移植/实现它。Crap4J试图通过暗示更复杂的代码(if,while,fors等)应该具有更高的测试覆盖率,来使代码覆盖率与圈复杂度相关联。对我来说,这个简单的想法确实是正确的。我想了解代码库中存在风险的地方,其中一项真正重要的风险是复杂性。因此,使用此工具,我可以快速评估我的代码库的风险。如果很复杂,覆盖范围最好增加。如果不是这样,我不需要浪费时间尝试覆盖每一行代码。

当然,这只是一个指标和YMMV。您必须花一些时间来了解它是否对您有意义,以及它是否会使您的团队对项目所在的位置有一个合理的了解。


非常感谢您提出使用圈复杂度来挑选值得覆盖和Crap4J链接的代码的建议。我还发现了一个伟大的文章,谈论挤压crap4j迷死到的Cobertura - schneide.wordpress.com/2010/09/27/...
MickJ

0

我不会说返回并覆盖现有代码是前进的最佳途径。我认为,为您编写的任何新代码和/或更改的任何代码编写覆盖测试都是有意义的。

发现错误后,编写一个由于该错误而失败的测试,并修复该错误,以使测试变为绿色。在测试的注释中输入编写的错误。

目的是对测试有足够的信心,使您可以进行更改而不必担心意外的副作用。请查看“有效使用旧版代码”,以很好地总结驯服未经测试的代码的方法。

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.