专栏首页搜狗测试浅谈代码覆盖率

浅谈代码覆盖率

前言

代码覆盖率作为一个指导性指标,可以一定程度上反应测试的完备程度,是软件质量度量的一种手段。100%覆盖的代码并不意味着100%无bug的应用,代码覆盖率作为质量目标没有任何意义,而我们应该把它作为一种发现未被测试覆盖的代码的手段。

代码覆盖率意义

1.了解测试情况

测试过程中覆盖和未覆盖的地方,可能存在的风险。分析未覆盖代码,反推在测试设计是否充分,进一步明确测试设计阶段的问题。

2.发现测试死角、冗余代码、历史废弃代码

有助于发现多个测试用例都覆盖不到的代码,收集方法覆盖率,为废弃的代码提供依据。

3.度量自动化用例

为自动化用例提供覆盖率统计情况,分析覆盖率报告,完善自动化用例。

4.精准回归

构建代码调用关系,精准的确定回归测试范围,避免了全量回归造成测试资源的浪费。

代码覆盖度量方法

1.语句覆盖(StatementCoverage)

又称行覆盖,段覆盖,基本块覆盖,这是最常用也是最常见的一种覆盖方式,就是度量被测代码中每个可执行语句是否被执行到了。语句覆盖常常被人指责为“最弱的覆盖”,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。

2.判定覆盖(DecisionCoverage)

又称分支覆盖,所有边界覆盖,基本路径覆盖,判定路径覆盖。它度量程序中每一个判定的分支是否都被测试到了。这句话是需要进一步理解的,应该非常容易和下面说到的条件覆盖混淆。因此我们直接介绍第三种覆盖方式,然后和判定覆盖一起来对比,就明白两者是怎么回事了。

3.条件覆盖(ConditionCoverage)

条件覆盖度量判定中的每个子表达式结果true和false是否被测试到了。

为了说明判定覆盖和条件覆盖的区别,我们来举一个例子,假如我们的被测代码如下:

int foo(int a, int b)

{ if (a < 10 || b < 10) // 判定 { return 0; // 分支一 } else { return 1; // 分支二 } }

设计判定覆盖案例时,我们只需要考虑判定结果为true和false两种情况,因此,我们设计如下的案例就能达到判定覆盖率100%:

TestCaes1: a =5, b = 任意数字 覆盖了分支一 TestCaes2: a =15, b =15 覆盖了分支二

设计条件覆盖案例时,我们需要考虑判定中的每个条件表达式结果,为了覆盖率达到100%,我们设计了如下的案例:

TestCase1: a =5, b =5true, trueTestCase4: a =15, b =15false, false

通过上面的例子,我们应该很清楚了判定覆盖和条件覆盖的区别。需要特别注意的是:条件覆盖不是将判定中的每个条件表达式的结果进行排列组合,而是只要每个条件表达式的结果true和false测试到了就OK了。因此,我们可以这样推论:完全的条件覆盖并不能保证完全的判定覆盖。比如上面的例子,假如我设计的案例为:

TestCase1: a =5, b =15true, false 分支一 TestCase1: a =15, b =5false, true 分支一

我们看到,虽然我们完整的做到了条件覆盖,但是我们却没有做到完整的判定覆盖,我们只覆盖了分支一。

4.路径覆盖(PathCoverage)

又称断言覆盖(PredicateCoverage)。它度量了是否函数的每一个分支都被执行了。这句话也非常好理解,就是所有可能的分支都执行一遍,有多个分支嵌套时,需要对多个分支进行排列组合,可想而知,测试路径随着分支的数量指数级别增加。

Java代码覆盖率原理

主流代码覆盖率工具都采用字节码插桩模式,通过钩子的方式来记录代码执行轨迹信息。其中字节码插桩又分为两种模式On-The-Fly和Offine。On-The-Fly模式优点在于无需修改源代码,可以在系统不停机的情况下,实时收集代码覆盖率信息。Offine模式优点在于系统启动不需要额外开启代理,但是只能在系统停机的情况下才能获取代码覆盖率。

On-The-Fly插桩 Java Agent

JVM中通过-javaagent参数指定特定的jar文件启动Instrumentation的代理程序代理程序在每装载一个class文件前判断是否已经转换修改了该文件,如果没有则需要将探针插入class文件中。代码覆盖率就可以在JVM执行代码的时候实时获取。典型代表:Jacoco

On-The-Fly插桩 Class Loader

自定义classloader实现自己的类装载策略,在类加载之前将探针插入class文件中。典型代表:Emma

Offine插桩

测试之前先对文件进行插桩,生成插过桩的class文件或者jar包,执行插过桩的class文件或者jar包之后,会生成覆盖率信息到文件,最后统一对覆盖率信息进行处理,并生成报告。Offine插桩又分为两种:Replace:修改字节码生成新的class文件Inject:在原有字节码文件上进行修改。典型代表:Cobertura、Jacoco

总结

本文主要介绍了代码覆盖率和Java覆盖率的统计原理。不管是白盒测试还是黑盒测试,代码覆盖率统计都是必不可少的一环,它可以直接反映测试的遗漏点(不是100%反映)。

最后重申下本文开篇观点:

  • 代码覆盖率统计是用来发现没有被测试覆盖的代码
  • 代码覆盖率统计不能完全用来衡量代码质量

本文分享自微信公众号 - 搜狗测试(SogouQA),作者:cp

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 前端代码覆盖率第一弹:准备阶段

    最近组内在建立持续集成流程,小编主要负责前端流程,截止到目前为止已经将整个流程梳理完毕在分阶段实施中,那么流程是什么样子的?具体怎么实施呢?一起来看看

    用户5521279
  • 测试利器之Mock server

    【问题分析】 通过Fiddler抓包查看请求,Moco Server已经返回了对应的XML文件,但是浏览器还是依然报错,如图所示:

    用户5521279
  • 测试数据不会造?Fake Data!

    在测试过程中,大家应该都遇到过各种各样的数据构造问题。e.g. 构造一批通讯录、构造一批用户三要素(姓名手机号身份证)、构造一批银行卡数据……

    用户5521279
  • 浅谈代码覆盖

    在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%。于是乎,测试人...

    大闲人柴毛毛
  • 前端代码覆盖率第一弹:准备阶段

    最近组内在建立持续集成流程,小编主要负责前端流程,截止到目前为止已经将整个流程梳理完毕在分阶段实施中,那么流程是什么样子的?具体怎么实施呢?一起来看看

    用户5521279
  • 微软与OpenAI达成合作,获得GPT-3独家使用授权

    当地时间9月22日,微软在官网发布通告,与OpenAI合作,独家获取了GPT-3语言模型的使用许可。

    大数据文摘
  • JavaScript实现私有属性

    JavaScript被很多人认为并不是一种面向对象语言,原因有很多种,比如JavaScript没有类,不能提供传统的类式继承;再比如JavaScript不能实现...

    寒月十八
  • 蚂蚁、字节、滴滴面试经历总结(都已过)

    在文章里我不仅会列出面试题,还会给到一些答题建议,个人能力有限,也不能保证我回答都正确,如果有错误,希望能纠正我。

    桃翁
  • c# typeof 与 GetType 作用与区别

    Used to obtain the "System.Type" object for a type. A 'typeof‘ expression takes ...

    用户2434869
  • Cypress web自动化39-.trigger()常用鼠标操作事件

    应该触发事件的位置。该center位置是默认位置。有效的位置topLeft,top,topRight,left,center,right,bottomLeft,...

    上海-悠悠

扫码关注云+社区

领取腾讯云代金券