测试覆盖率 聊聊度量测试覆盖率的几种方式

肖哥shelwin · 2019年07月14日 · 最后由 肖哥shelwin 回复于 2019年07月17日 · 4230 次阅读

测试覆盖率(test coverage) 是衡量软件测试完整性的一个重要指标。掌握测试覆盖率数据,有利于客观认识软件质量,正确了解测试状态,有效改进测试工作。

当然,要发挥这些作用,前提是我们掌握了真实的测试覆盖率数据。通常这并不是一件很直接的事情。那么,如何度量测试覆盖率呢?

在度量测试覆盖率之前,我们需要明确测试覆盖率的定义。毕竟,不同的定义会产生完全不同的覆盖率数据。这里,我基于个人认知和经验,总结三种最常见的测试覆盖率定义及度量方法。

最著名的测试覆盖率就是代码覆盖率。这是一种面向软件开发和实现的定义。它关注的是在执行测试用例时,有哪些软件代码被执行到了,有哪些软件代码没有被执行到。被执行的代码数量与代码总数量之间的比值,就是代码覆盖率

这里,根据代码粒度的不同,代码覆盖率可以进一步分为源文件覆盖率,类覆盖率,函数覆盖率,分支覆盖率,语句覆盖率等。它们形式各异,但本质是相同的。

如何度量代码覆盖率呢?一般可以通过第三方工具完成。不同编程语言,有不同的工具。例如 Java 语言有 Jacoco,Go 语言有 GoCov,Python 语言有 Coverage.py。

这些度量工具有个特点,那就是它们一般只适用于白盒测试,尤其是单元测试。对于黑盒测试 (例如功能测试/系统测试) 来说,度量它们的代码覆盖率则相对困难多了。

主流编程语言一般都有现成的单元测试覆盖度工具,拿过来稍作配置即可使用。但是,如果想更进一步去了解这些工具背后的实现原理,就需要花费一些功夫了。

以 Python 覆盖率工具 Coverage.py 为例,它包括执行,分析和生成报告三大模块。最核心的执行模块依赖 Python 内置的 trace 函数。这是一个由 Python 解释器提供的,当每一行 Python 代码被执行时所激活的函数。

基于 trace 函数,我们可以得到每一行被执行的代码所在的文件和行数。然后,结合软件源代码,我们就可以分析出测试的代码覆盖情况,最后生成覆盖报告。

对于黑盒测试,例如功能测试/集成测试/系统测试等来说,测试用例通常是基于软件需求而不是软件实现所设计的。因此,度量这类测试完整性的手段一般是需求覆盖率,即测试所覆盖的需求数量与总需求数量的比值

需求粒度的不同,需求覆盖率的具体表现也有不同。例如,系统测试针对的是比较粗的需求,而功能测试针对的是比较细的需求。当然,它们的本质是一致的。

如何度量需求覆盖率呢?通常没有现成的工具可以使用,而需要依赖人工计算,尤其是需要依赖人工去标记每个测试用例和需求之间的映射关系

对于黑盒测试来说,由于测试是基于用户场景而不是软件实现设计的。因此,这个时候去度量软件代码覆盖率,其意义并不显著,至少是不如需求覆盖率的。

代码覆盖率和需求覆盖率有一个共同点,即它们都是面向测试过程的指标。因此有个不足之处,即覆盖率数据可能无法完全反映真实的测试状态和水平

对于代码覆盖率来说,广为诟病的一点就是 100% 的代码覆盖率并不能说明代码就被完全覆盖没有遗漏了。因为代码的执行顺序和函数的参数值,都可能是千变万化的。一种情况被覆盖到,不代表所有情况被覆盖到。

对于需求覆盖率来说,100% 的覆盖率也不能说 “万事大吉”。因为需求可能有遗漏或存在缺陷,测试用例与需求之间的映射关系,尤其是用例是否真正能够覆盖对应的测试需求,也可能是存在疑问的。

测试的目的是发现软件缺陷。因此,衡量测试完整性的终极指标应该是面向测试结果的缺陷覆盖率,即测试所实际发现的缺陷数量与测试所应该发现的缺陷总量的比值

软件测试一般是分为多个测试阶段的。每个阶段有每个阶段的任务。对于当前测试阶段来说,在后续阶段发现的缺陷中,属于当前阶段 (而不是更早阶段)遗漏出去的缺陷是我们需要重点关注的。

虽然讨论缺陷覆盖率有一种 “事后诸葛亮” 的感觉,但是它的意义是不容忽视的。一方面它提供了评价某一阶段测试工作成效的重要指标,另一方面它为我们改进测试工作提供了重要参考。例如,针对每一个遗漏缺陷深入挖掘,举一反三,可以避免同类问题在未来再次发生。

总结一下,这里介绍了三种常见的测试覆盖率的定义和度量方法,分别是代码覆盖率,需求覆盖率和缺陷覆盖率。它们适用于不同的场景,有各自的优势与不足。需要注意的是,它们不是互相排斥,而是相互补充的。

关于测试覆盖率,最重要的一点应该是迈出第一步,即有意识地去收集这种数据。没有覆盖率数据,测试工作会有点像在 “黑灯瞎火” 中走路。有了覆盖率数据,并持续监测,利用和改进这个数据,才是一条让测试工作越来越好的光明大道。

我是肖哥 shelwin,一个高质量软件工程实践者和推动者。欢迎添加我的个人公众号测试不将就或关注同名博客,谢谢,获得更多自动化测试, 持续集成, 软件工程实践, Python 编程等领域原创文章。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 16 条回复 时间 点赞
jeky2017 回复

谢谢支持 -:)

16楼 已删除

质量保障工作是项长期工作,还在不断摸索中,感谢楼主分享。

肖哥shelwin 回复

死老外发明的敏捷 然后国内的辣鸡管理又乱改敏捷弄成了四不像的辣鸡东西

simple 回复

代码覆盖率确实很基础,也很客观。把重心放在代码覆盖率上面是可以的。尤其是如果能够把黑盒测试的代码覆盖率给搞明白就更好了

胖虎 回复

谢谢意见!缺陷覆盖率确实有点 KPI 的意思,见过把这个作为测试团队成绩向领导请功的😂

16楼 已删除

我们刚刚才把代码覆盖率体系建立起来,对于缺陷覆盖率和需求的度量统计还没有找到科学的计算方式,对于需求和 tag 进行关联,楼主公司做的很严格了,在一些公司,需求如果没有很好的管理系统来制约的话,会有五花八门的提交方式,比如我们就有用 word、excel、在线文档地址、axure、email、IM 聊天软件口述讨论等等,诸如此类的需求来源渠道。个人觉得目前最有效的方式应该是通过代码覆盖率来反推 case,做到增量代码提交没有重大的逻辑遗漏,这个我们是通过 code review 来保障的。另外就是对一些项目做冗余代码清理,这个我们目前收效还可以。

关于 代码覆盖率,分析的挺详细的,非常不错。
关于 缺陷覆盖率,我个人不太赞同这种做法,原因有 2:
数字化、报表化管理,走 KPI 形式,与敏捷文化不契合;
事后分析于事无补,缺陷是由人来提出来的,人的因素在其中作为参数变量不科学。
建议:统计缺陷覆盖率,不如做 缺陷分析讨论会,重点挖掘没有发现的缺陷,举一反三。

以上个人愚见

陈恒捷 回复

在我们这里,是通过 tag 实现的。每个需求会有编号,每个测试用例都会打上 tag,标记的是对应的需求的编号。这样,哪些需求被哪些用例被覆盖到,哪些需求没有用例覆盖,就比较清楚的。例如,Robot Framework 就支持给用例添加 tag:https://stackoverflow.com/questions/22314808/how-do-you-add-tags-to-data-driven-tests-in-robot-framework

需求覆盖率 这个有没有更具体的一些参考度量方式供参考?

很多时候需求并非想用例那样一条一条来的,大多是一个文档或者原型,按模块划分。文中提到的用例和需求映射关系,感觉好像不大好落地?

敏捷确实让人很难停下来歇息会,节奏太快了。

hanhero07 回复

谢谢支持!

槽神 回复

谢谢大佬指教 😂 "Rayleigh Distribution"看起来蛮厉害的,我去了解下。

长见识了,记下来了;只是背背书,不能当真;也不晓得 那个狗日的,提出 和 那个死缺德,搞出来了 所谓的 敏捷开发;无限的压榨 人员的时间和精力;

缺陷覆盖率,这词造的有点太过生硬了,一般叫缺陷消除率
各阶段的缺陷消除率可以通过数学建模,用于推算下一个阶段或者线上遗留的缺陷数,请自行百毒 “Rayleigh Distribution” 或者查看别人的文章:http://www.51testing.com/html/64/n-861264.html

以前只知道代码覆盖率,没想到还有需求覆盖率和缺陷覆盖率。感谢分享,长见识了!

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册