CI做到90%的行覆盖率,真能发现BUG吗?

简介: 阿里妹导读:这么多的CASE,花了大量时间和资源去运行,真能发现BUG吗?CI做到90%的行覆盖率,能发现问题吗?测试用例越来越多,删一些,会不会就发现不了问题了?今天,我们谈谈如何评估测试用例的有效性?

image
阿里妹导读:这么多的CASE,花了大量时间和资源去运行,真能发现BUG吗?CI做到90%的行覆盖率,能发现问题吗?测试用例越来越多,删一些,会不会就发现不了问题了?今天,我们谈谈如何评估测试用例的有效性?

我们的测试用例有两个比较关键的部分:

1)调用被测代码:例如下面的RuleService.getLastRuleByClientId(ClientId)。
2)进行结果Check:例如下面的AssertEqual(OrderId,"ABCD1234")。

TestCaseA
...
  RuleService.createRuleByClientId(ClientId,RuleDO);
  StringOrderId=RuleService.getLastRuleByClientId(ClientId);
...
  
TestCaseB
...
  RuleService.createRuleByClientId(ClientId,RuleDO);
  StringOrderId=OrderService.getLastOrderByClientId(ClientId);
  AssertEqual(OrderId,"ABCD1234");
...

我们希望一组测试用例不仅能够“触发被测代码的各种分支”,还能够做好结果校验。

  • 当业务代码出现问题的时候,测试用例可以发现这个问题,我们就认为这一组测试用例是有效的。
  • 当业务代码出现问题的时候,测试用例没能发现这个问题,我们就认为这一组测试用例是无效的。

我们对测试用例有效性的理论建模是:

测试有效性 = 被发现的问题数 / 出现问题的总数

为什么要评估测试用例的有效性?

image

测试用例有效性评估的方法?

基于故障复盘的模式成本太高,我们希望能够主动创造问题来评估测试用例的有效性。

我们找到了一种衡量“测试有效性”的方法,变异测试(mutation testing):

image

变异测试的例子

我们用了一组测试用例(3个),去测试一个判断分支。
而为了证明这一组测试用例的有效性,我们向业务代码中注入变异。我们把b<100的条件改成了b<=100。

我们认为:

  • 一组Success的测试用例,在其被测对象发生变化后(注入变异后),应该至少有一个失败。
  • 如果这组测试用例仍然全部Success,则这组测试用例的有效性不足。

通过变异测试的方式:让注入变异后的业务代码作为“测试用例”,来测试“测试代码”。

我们实现了多种规则,可以主动的注入下面这些变异:

image

如何优雅的评估测试有效性?

为了全自动的进行测试有效性评估,我们做了一个变异机器人,其主要运作是:

  1. 往被测代码中写入一个BUG(即:变异);
  2. 执行测试;
  3. 把测试结果和无变异时的测试结果做比对,判断是否有新的用例失败;
  4. 重复1-3若干次,每次注入一个不同的Bug;
  5. 统计该系统的“测试有效性” 。

image

变异机器人的优点:

  1. 防错上线:变异是单独拉代码分支,且该代码分支永远不会上线,不影响生产。
  2. 全自动:只需要给出系统代码的git地址,即可进行评估,得到改进报告。
  3. 高效:数小时即可完成一个系统的测试有效性评估。
  4. 扩展性:该模式可以支持JAVA以及JAVA以外的多种语系。
  5. 适用性:该方法不仅适用于单元测试,还适用于其他自动化测试,例如接口测试、功能测试、集成测试。

变异机器人的使用门槛:

  1. 测试成功率:只会选择通过率100%的测试用例,所对应的业务代码做变异注入。
  2. 测试覆盖率:只会注入被测试代码覆盖的业务代码,测试覆盖率越高,评估越准确。

高配版变异机器人

我们正在打造的高配版变异机器人拥有三大核心竞争力:

分钟级的系统评估效率

为了保证评估的准确性,100个变异将会执行全量用例100遍,每次执行时间长是一大痛点。

高配版变异机器人给出的解法:

  1. 并行注入:基于代码覆盖率,识别UT之间的代码覆盖依赖关系,将独立的变异合并到一次自动化测试中。
  2. 热部署:基于字节码做更新,减少变异和部署的过程。
  3. 精准测试:基于UT代码覆盖信息,只运行和本次变异相关的UT(该方法不仅适用于UT,还适用于其他自动化测试,例如接口测试、功能测试、集成测试)。

学习型注入经验库

为了避免“杀虫剂”效应,注入规则需要不断的完善。

高配版变异机器人给出的解法:故障学习,基于故障学习算法,不断学习历史的代码BUG,并转化为注入经验。可学习型经验库目前覆盖蚂蚁金服的代码库,明年会覆盖开源社区。

兼容不稳定环境

集成测试环境会存在一定的不稳定,难以判断用例失败是因为“发现了变异”还是“环境出了问题”,导致测试有效性评估存在误差。

高配版变异机器人给出的解法:

  1. 高频跑:同样的变异跑10次,对多次结果进行统计分析,减少环境问题引起的偶发性问题。
  2. 环境问题自动定位:接入附属的日志服务,它会基于用例日志/系统错误日志构建的异常场景,自动学习“因环境问题导致的用例失败”,准确区分出用例是否发现变异。

落地效果如何?

我们在蚂蚁金服的一个部门进行了实验,得出了这样的数据:

image

换言之,几个系统的测试有效性为:系统A 72%,系统B 56%,系统C 70%。

测试有效性(%) = 1 - 未发现注入数 / 注入数

更多的测试有效性度量手段

基于代码注入的测试有效性度量,只是其中的一种方法,我们日常会用到的方法有这么几种:

  • 代码注入:向代码注入变异,看测试用例是否能发现该问题
  • 内存注入:修改API接口的返回内容,看测试用例是否能发现该问题
  • 静态扫描:扫描测试代码里是否做了Assert等判断,看Assert场景与被测代码分支的关系
  • ... 还有更多其他的度量手段

Meet the testcase again

测试有效性可以作为基石,驱动很多事情向好发展:

  • 让测试用例变得更能发现问题。
  • 让无效用例可被识别、清理。
  • 创造一个让技术人员真正思考如何写好TestCase的质量文化。
  • 测试左移与敏捷的前置条件。
  • ......

写到最后,想起了同事给我讲的一个有趣的人生经历:

“大二期间在一家出版社编辑部实习,工作内容就是校对文稿中的各种类型的错误。编辑部考核校对质量的办法是,人为的事先在文稿中加入各种类型的错误,然后根据你的错误发现率来衡量,并计算实习工资。”

“你干得咋样?”

“我学习了他们的规则,写了个程序来查错,拿到了第一个满分”

“厉害了...”

“第二个月就不行了,他们不搞错别字了,搞了一堆语法、语义、中心思想的错误... 我就专心干活儿了”

“...”

殊途同归,其致一也。

原文发布时间为:2019-09-27
作者:义理
本文来自云栖社区合作伙伴“阿里技术”,了解相关信息可以关注“阿里技术”。

相关文章
|
6月前
|
测试技术
测试提交的bug开发不认可怎么办?
测试提交的bug开发不认可怎么办?
179 0
|
1月前
|
安全 测试技术
北大李戈团队提出大模型单测生成新方法,显著提升代码测试覆盖率
【10月更文挑战第1天】北京大学李戈教授团队提出了一种名为“统一生成测试”的创新方法,有效提升了大模型如GPT-2和GPT-3在单一测试中的代码生成覆盖率,分别从56%提升至72%和从61%提升至78%。这种方法结合了模糊测试、变异测试和生成对抗网络等多种技术,克服了传统测试方法的局限性,在大模型测试领域实现了重要突破,有助于提高系统的可靠性和安全性。然而,该方法的实现复杂度较高且实际应用效果仍需进一步验证。论文可从此链接下载:【https://drive.weixin.qq.com/s?k=ACAAewd0AA48Z2kXrJ】
62 1
|
4月前
|
测试技术
codereview开发问题之CodeReview关注代码的测试覆盖率问题如何解决
codereview开发问题之CodeReview关注代码的测试覆盖率问题如何解决
|
6月前
|
测试技术
项目上线后发现bug,该怎么办?
项目上线后发现bug,该怎么办?
163 0
|
6月前
|
SQL 前端开发 测试技术
软件测试/测试开发|如何定位bug,一篇文章告诉你
软件测试/测试开发|如何定位bug,一篇文章告诉你
|
运维 Kubernetes jenkins
测试流程--测试发版规范
为了保证系统稳定性,对软件项目的上线过程进行规范,确保项目符合产品需求。对于已经开发完毕的系统,需要正式部署到生产环境前必须严格按照以下流程规范实施。 规范发版的流程,指定发版的相关输出,相关信息的收集,并通知相关业务方了解发版信息。防止或减少因发版造成的系统抖动对业务产生的影 响,并有利于追溯发版过程,方便后续优化迭代。
1630 0
测试流程--测试发版规范
|
运维 Java 测试技术
重构性项目如何回归测试?
重构性项目如何回归测试?
|
测试技术
如何处理不能复现的bug?软件测试工程师避坑指南
软件测试工作中常常会遇到不能复现的bug,遇到这种情况其实很正常,但是很多测试新手都按照自己的想法处理,没有提交bug,或者匆匆关闭bug。线上出现问题,就只能自己背锅了。
555 0
|
Web App开发 关系型数据库 项目管理
|
存储 Java 程序员
BeanDifinition(加几行代码,可以产出让队友几天也找不出的Bug)
前言 文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820… 种一棵树最好的时间是十年前,其次是现在
190 0