在作单元测试时,代码覆盖率经常被拿来做为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成状况。可是我相信,你不是为了覆盖率才要求覆盖率的。你须要有意义的覆盖率,以代表你已经很好地测试了该软件。安全
衡量代码覆盖率相关的问题老是可以引发个人注意。一方面,我常常发现,公司和组织不必定知道他们在测试期间覆盖了多少代码,这确实很使人惊讶!另外一方面,对于一些组织来讲,代码覆盖率的数字是如此重要,以致于测试的质量和有效性却变得几乎可有可无了。他们盲目地追逐100%的代码覆盖率,并相信,若是拥有这个数字,该软件将是优秀的,甚至多是最好的。其实,这样跟不知道你所测试的内容同样危险,实际上可能更危险,由于它可能给你带来错误的安全感。架构
代码覆盖率能够用来评估软件质量,这是一个很好且有趣的数字,但请务必记住,这是一种手段,而非目的。咱们并非为了覆盖率而要求覆盖率,由于它应该代表咱们在测试软件方面作得很好。若是测试自己没有意义,那么再高的覆盖率也并不意味着软件会更好。重要的目标是确保测试每一个代码,而不只仅是执行代码。没有足够的时间和金钱来全面测试全部内容,至少要确保对全部重要的内容都进行了测试。框架
这就是说,低覆盖率意味着咱们可能测试不足,而高覆盖率自己并不必定与高质量相关联——实际状况要复杂得多。工具
显然,拥有一个愉快的测试环境,使你拥有“足够”的覆盖率,能够放心使用一个良好、稳定、可维护的测试套件来发布软件,该套件具备“足够的测试”,这是最好的状态。可是,实际上,这些覆盖率陷阱仍然很常见。单元测试
不知道本身的代码覆盖率彷佛并不合理——市面上的代码覆盖率工具既便宜又丰富。个人一个朋友告诉我,其实开发人员通常都知道本身的代码覆盖率不理想,所以开发人员和测试人员不肯将覆盖率不高的漏洞暴露给管理层。固然我但愿这不是广泛的状况。测试
团队在尝试评估覆盖率时遇到的一个实际问题是该系统过于复杂。当你逐块构建应用程序时,仅知道将覆盖范围计数器放置在何处多是一项艰巨的任务。我建议,若是实际上很难衡量应用程序的覆盖范围,则应该对架构进行三思。spa
陷入这种陷阱的第二种方法发生在可能进行大量测试但没有实际覆盖数量的组织中,由于他们没有找到合适的方法来汇总来自不一样测试运行的数量。若是你要进行手动测试、功能测试、单元测试和端到端测试,则不能简单地将数字加起来。即便它们各自实现了25%的覆盖率,结合起来也不太可能达到100%。实际上,当您查看结果时,它更可能接近25%,而不是100%。blog
事实证实,实际上存在一种以有意义的方式一块儿测量和增长覆盖范围的方法。在Parasoft,利用报告和分析工具Parasoft DTP捕获的大量细粒度数据,能够在这种状况下使用它来提供全面、汇总的代码覆盖率视图。应用程序监视器可以在测试过程当中直接从应用程序中收集覆盖率数据,而后将其发送到Parasoft DTP,后者会汇总全部测试实践以及测试团队和测试运行中的覆盖率数据。开发
若是听起来像是包含了至关大的信息量,那你是对的!DTP提供了一个交互式仪表板,可帮助你浏览此数据并就将测试重点放在哪里作出决策。请参阅下面的示例仪表板:test
若是多个测试覆盖了相同的代码,则不会被计算在内,而未经测试的代码部分则能够快速、轻松地看到。这向你显示了应用程序的哪些部分已通过良好的测试,哪些没有通过测试。你能够在免费的白皮书中阅读全部内容。
所以,没有更多的借口不衡量覆盖率。
人们经常误觉得覆盖率就是一切。一旦团队可以衡量覆盖率,领导一般会说“让咱们来增长这个数字”。最终,数字自己变得比测试更重要。正如Parasoft的创始人Adam Kolawa所说的:
“这就像要求钢琴家按照100%的覆盖率敲击钢琴琴键,而不是根据曲谱的须要仅敲击那些有意义的琴键。当他演奏做品时,他会得到有意义的任何数量的按键覆盖。”
问题就出在这里——盲目的要求覆盖率与盲目的音乐演奏相同。覆盖率须要反映出对代码的真实、有意义的使用,不然只会是“噪音”。
说到“噪音”……覆盖率的成本会随着覆盖率的增长而增长。请记住,你不只须要建立测试,并且还必须维护它们。若是你不打算重复使用和维护测试,则可能一开始就不要浪费时间来建立它。随着测试套件的变大,“噪音”量也会以意想不到的方式增长。两倍的测试可能意味着两倍甚至三倍的“噪音”。无心义的测试最终会比好的测试产生更多的“噪音”,由于它们没有真实的上下文,可是每次执行测试时都必须加以处理。想想技术债务吧!无用的测试是真正的危险。
如今,在某些行业(例如对安全相当重要的行业)中,必须达到100%的覆盖率指标。可是即便在这种状况下,将一行代码的任何执行都视为有意义的测试也太容易了,这根本不是事实。我要问两个基本问题,以肯定一个测试是不是一个好的测试:
理想状况下,当测试失败时,咱们会知道出了什么问题,若是测试真的很好,它将为咱们指明正确的方向进行修复。当测试失败时,不少时候没有人知道为何,没有人能够复制它,而测试被忽略了。相反,当测试经过时,咱们应该可以知道所测试的内容——这意味着某个特定功能或某项功能正常运行。
若是您不能回答其中一个问题,则多是你的测试有问题。若是你不能回答它们中的任何一个,则测试带来的麻烦可能比它产生的价值更多。
摆脱陷阱的方法首先是要了解覆盖率自己并非目标。真正的目标是建立有用的有意义的测试。这固然须要时间。在简单的代码编写中,单元测试很简单,可是在复杂的实际应用程序中,这意味着编写存根和模拟并使用框架。这可能会花费不少时间,若是你一直不这样作,很容易忘记所涉及的API的细微差异。即便你认真对待测试,建立真正好的测试所花费的时间也可能比你预期的要长。
为了提升单元测试的效率,Java开发测试工具Parasoft Jtest中有一个针对于此的新技术——单元测试助手。单元测试助手承担着完成正确的模拟和存根的繁琐任务。它也能够帮助你以一种有效的方式来扩展示有测试,以增长覆盖范围——帮助你建立良好的单元测试,并提出建议以提升测试覆盖率和测试质量。
但愿你已经了解到覆盖率的重要性,而且提升覆盖率是一个值得实现的目标。可是请记住,单纯的追求百分比并无编写稳定、可维护和有意义的测试更有价值。