测试覆盖率通常用来衡量测试的充分性和完整性。

从广义来讲,大致分为业务层面的需求覆盖率和技术层面的代码覆盖率

一、需求覆盖率

通常通过需求管理工具,来建立需求和测试用例的对应关系,并以此来计算测试覆盖率。

需求覆盖率的统计方法属于比较重量级的方法体系,属于传统瀑布模式下的软件工程实践,很难适应当今互联网时代下的敏捷开发实践。

所以,互联网测试项目中很少基于需求来衡量测试覆盖率,而是将软件需求转换成测试需求,因此互联网企业中涉及的需求覆盖率通常默认指代码覆盖率

只有少数沿用瀑布开发模型的传统型软件企业还在继续使用需求覆盖率来衡量测试的完备性。

二、代码覆盖率

简单来说,代码覆盖率是指,至少执行了一次的条目数占整个条目数的百分比。

如果"条目数"是语句,对应的就是行覆盖率

如果"条目数"是函数,对应的就是函数覆盖率

如果"条目数"是路径,对应的就是路径覆盖率

简单介绍一下最常用的几种代码覆盖率指标:

  • 行覆盖率又称语句覆盖率,指已执行的语句占全部可执行语句(不包含类似C++的头文件声明,代码注释,空行等)的百分比。这是最常用也是要求最低的覆盖率指标。实际项目中通常会结合判定覆盖率和条件覆盖率一起使用。
  • 函数覆盖率又称方法覆盖率,指的是执行到的函数占总函数数量的百分比。
  • 判定覆盖率又称分支覆盖率,用于度量程序中的每一个判断的分支是否都被测试到了,即代码中的每个判断的取真分支和取假分支是否均覆盖到了最少一次,比如对于if(a>0&&b>0)就要求覆盖true和false各一次。
  • 条件覆盖率是指每个条件的取值至少满足一次,用于度量判断的每个条件的结果(true和false)是否都测试到了,比如对于if(a>0&&b>0),要求a>0取到true和false各一次,b>0也要取到true和false各一次。
  • 条件/判断覆盖率指需要同时满足判断覆盖率和条件覆盖率。
  • 修改条件/判断覆盖率是一个要求最高的覆盖率指标。在一些与安全息息相关的应用中,一般会需要满足修改条件判断覆盖的准则。此准则是条件/判断覆盖的延伸,而且每个条件都要影响判断结果成立还是不成立。例如以下语句:
if (a or b) and c then

以下测试可以满足条件/判断覆盖率

a=true,b=true,c=true

a=false,b=false,c=false

不过若要求第一项测试中的b的值改为false,不影响判断结果,第二项测试中的c的值改为true,不影响判断结果,就需要用以下的测试来满足修改条件/判断覆盖率

a=false,b=false,c=true

a=true,b=false,c=true

a=false,b=true,c=true

a=true,b=true,c=false

其中粗体的条件表示影响判断结果的条件。在影响判断结果的条件中,每个变量都出现至少两次,其中至少一次其值为true,至少一次其值为false。

代码覆盖率的价值

现在很多项目都在单元测试以及集成测试阶段统计代码覆盖率,但是统计代码覆盖率仅仅是手段,我们必须透过现象看事务的本质,才能从根本上来保证软件整体的质量。

统计代码覆盖率的根本目的是找出潜在的遗漏测试用例,并针对性的进行补充,同时还可以识别出代码中那些由于需求变更等原因造成的不可用的废弃代码

通常我们希望代码覆盖率越高越好。代码覆盖率越高,越能说明测试用例设计是充分且完备的。但是你也发现测试成本随着代码覆盖率的提高以接近指数级的方式迅速增加。如果想达到70%的代码覆盖率,可能需要30min的时间,但是如果想达到90%,就会花费远远不止30min的时间。而想要达到100%的代码覆盖率,花费的时间成本就会更高。

为什么代码覆盖率的提高,需要付出越来越大的代价呢?

因为在后期需要大量的桩代码,Mock代码,和全局变量的配合来控制执行路径。

所以软件企业中只有单元测试阶段对代码覆盖率有较高的要求。因为从技术实现上讲,单元测试可以最大化地利用打桩技术来提高覆盖率。而在集成测试或GUI测试阶段将代码覆盖率提到一定百分比,所要付出的代价将是巨大的,而且在很多情况下根本就实现不了。

代码覆盖率的局限性

如果你通过努力,已经把某个函数的MC/DC(修改条件/判断覆盖率,代码覆盖率的最高标准,一般项目除了直接关系人生命安全,很少会严格要求MC/DC)提高到了100%,软件质量就真的高枕无忧,万无一失了吗?

即使你所设计的用例已经达到100%的代码覆盖率,软件产品的质量也做不到万无一失,其根本原因在于代码覆盖率的计算是基于现有代码的,并不能发现那些"未考虑某些输入"以及"未处理某些情况"形成的缺陷。

例如,如果一个被测函数里面只有一行代码,只要这个函数被调用了,那么衡量这一行代码质量的所有覆盖率指标都会是100%,但是这个函数是否真正实现了应该需要实现的功能呢?显然,代码覆盖率反映的仅仅是已有代码的哪些逻辑执行过了,哪些逻辑还没有执行过,以此为依据,可以补充测试用例,可以以测试那些还没有覆盖到的执行路径,但仅此而已。对于那些完全还没有代码实现的部分就无能为力了。

总体来讲,高的代码覆盖率不一定能保证软件的质量,但是低的代码覆盖率一定不能保证软件质量。

关于代码覆盖率的报告

以统计Java语言代码覆盖率的工具JaCoCo为例,介绍一下代码覆盖率工具生成的统计报告。

JaCoCo可以很方便的嵌入到Ant,Maven中,并且和很多主流的持续集成工具以及代码静态检查工具(如Jenkins和Sonar等)有很好的集成。

代码覆盖率统计报告,包括了每个Java代码文件的行覆盖率,分支覆盖率的统计,并给出了每个Java代码文件的行数,方法数和类数等具体信息。

文件内部详细的代码覆盖率如下图所示:

其中绿色的行表示已覆盖,黄色的行表示部分覆盖,红色的行表示未覆盖。

左侧绿色菱形块表示该分支已经完全覆盖,黄色菱形块表示分支仅部分覆盖,红色菱形块表示分支未覆盖。

显然,通过这个详尽的报告,就可以知道代码的真实执行情况,哪些代码未被覆盖。以此为基础再去设计测试用例就会更有针对性了。

代码覆盖率工具的实现技术

实现代码覆盖率的统计,最基本的方法就是注入。简单地说,注入就是在被测代码中自动插入用于覆盖率统计的探针(Probe),并保证插入的探针代码不会对原代码带来任何影响。

对于Java代码来讲,根据注入目标不同,可以分为源代码注入和字节码注入两大类。

基于JVM本身特性和执行效率的原因,目前主流工具基本都是使用字节码注入,注入的具体实现采用ASM技术,ASM是一个Java字节码操纵框架,能用来动态生成类或者增强既有类的功能,可以直接产生class文件,可以在类加载到JVM中之前动态改变类行为。

根据注入发生的时间点,字节码注入又可以分两大模式:即时注入(On-The-Fly)模式和离线注入(Offline)模式。

1.即时注入模式

即时注入模式的特点在于无须修改源代码,也无需提前进行字节码插桩,适用于支持Java代理的运行环境。这样做的优点是可以在系统不停机的情况下,实时收集代码覆盖率的信息。缺点是运行环境必须使用Java代理。

实现即时注入模式主要有两种技术方案。

(1)开发自定义类加载器,实现类装载策略,每次加载类前,需要在Class文件中插入探针,早期Emma就是使用这种方式实现探针插入。

(2)借助Java代理,利用在main()方法之前执行的拦截器方法premain()来插入探针,实际使用过程中需要在JVM的启动参数中添加“-javaagent”,并指定用于实现字节码注入的代理程序,这样代理程序在装载每个Class文件前,先判断是否已经插入了探针,目前主流的JaCoCo就使用这种方式。

2.离线注入模式

离线注入模式也无须修改源代码,但是需要在测试开始之前先对文件进行插桩,并提前生成插过桩的Class文件。它适用于不支持Java代理的运行环境,以及无法使用自定义类加载器的场景。这样做的优点是,JVM启动时不再需要额外开启代理,缺点是无法实时获取代码覆盖率信息,只能在系统停机时获取。

离线模式根据生成新的Class文件还是直接修改原Class文件,又可分为替换和插入两种模式。和即时注入不同,替换和插入,在测试运行前就已经通过ASM将探针插入了Class文件,而在测试的运行过程中不需要任何额外的处理。Cobertura就是使用离线模式的典型代表。

如何理解软件的测试覆盖率?相关推荐

  1. 软件测试中语句覆盖的优点,软件测试之测试覆盖率的基本策略

    原标题:软件测试之测试覆盖率的基本策略 软件测试覆盖率简介 1.定义:覆盖率是用来度量测试完整性的一个手段,同时也是测试技术有效性的一个度量. 2.计算:覆盖率=(至少被执行一次的item数)/ite ...

  2. 软件分支测试覆盖率 100%,测试覆盖率之三——测试覆盖率100%相关的话题

    上一篇文章中,介绍了测试覆盖率的意义之类的东西.测试覆盖率可以帮助我们检查测试质量,检查测试用例的有效率.如果有兴趣的话,可以阅读测试覆盖率之二--测试覆盖率有什么用? 关于测试覆盖率,我个人的感觉是 ...

  3. 软件测试之-测试覆盖率

    软件测试覆盖率简介 1.定义:覆盖率是用来度量测试完整性的一个手段,同时也是测试技术有效性的一个度量.2.计算:覆盖率=(至少被执行一次的item数)/item的总数3.特点1)通过覆盖率数据,可以检 ...

  4. 用Cobertura 测量测试覆盖率

    Cobertura 是一种开源工具,它通过检测基本的代码,并观察在测试包运行时执行了哪些代码和没有执行哪些代码,来测量测试覆盖率.除了找出未测试到的代码并发现 bug 外,Cobertura 还可以通 ...

  5. 在持续交付阶段中的测试覆盖率(译)

    测试覆盖率是一项帮助我们在恰当优先级下使用稀少测试时间的一项策略.当最后东西被测试完,我们有多少自动化覆盖,用户使用这特性多经常,并且对应用程序来说这特性有多关键这些都是要考虑的因素.这儿有一些在你转 ...

  6. 测试用例的设计-提高测试覆盖率

    前言 说到测试用例的设计,我想每个有过测试经历的测试工程师都会认为很简单,不就是:按需求或概要设计,得到软件功能划分图,然后据此按每个功能,采用等价类划分.临界值.因果图等方法来设计用例就行了. 但事 ...

  7. Node.js 单元测试:我要写测试 - Mocha - Nodejs开源项目里怎么样写测试、CI和代码测试覆盖率

    -------------------------------------- 单元测试Express/NodeJs 个人理解, 1,如果不是测试http请求的单元测试,用Mocha, Chai等基本够 ...

  8. 全程软件测试之测试需求分析与计划(1)

    在项目启动之后,就要着手软件项目的计划,包括软件测试计划.软件测试计划是整个开发计划的组成部分,同时,它又依赖于软件组织过程.项目的总体计划.质量文化和方针.在测试计划活动中,首先要确认测试目标.范围 ...

  9. Software Testing - 测试用例设计之如何提高测试覆盖率

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 前言 说到测试用例的设计,我想每个有过测试经历的测试 ...

最新文章

  1. HDU(1856),裸的带权并查集
  2. 从搜索引擎到社交网络的艰难转变
  3. c# 链接mongDB集群实战开发
  4. LeetCode 929. 独特的电子邮件地址
  5. 【光说不练假把式】今天说一说Kubernetes 在有赞的实践
  6. 混合App开发,HBuilder开发移动App
  7. python iocp_[网络开发]IOCP完整例子
  8. Android Frame动画概述及示例
  9. 动态调试 ida linux,IDA动态调试-ELF
  10. 深度学习之----各种学习策略
  11. qmap按插入顺序排序_C++语言排序算法之插入排序
  12. android 自定义相机,Android应用开发之android 7自定义相机预览及拍照功能
  13. 9.触摸屏驱动(IIC)移植实战
  14. 怎么在PDF文档中为文字添加下划线
  15. 手机按公式计算机,请问用手机上的自带计算器怎样进行度分秒的计算?
  16. java String字符串去除()里的内容
  17. python-多元线性回归模型
  18. 罗振宇《时间的朋友》2017跨年演讲摘要
  19. 蓝颜知己的伤感空间日志发布:想你,是一种,刻骨铭心的痛
  20. php安装xmeet,XMeet下载-XMeet官方版下载V1.8.4-99wo下载站

热门文章

  1. 手把手教你开通和使用融资融券账户!
  2. MEV生态系统中的价值流动
  3. 远离流氓软件 - 清除流氓软件工具大合集,欢迎补充!
  4. 《精益创业》读后思考 2
  5. mousedown、mousemove、mouseup实现一个可拖拽的div
  6. win10计算机内的快捷图标,win10系统任务栏添加计算机快捷图标的图文办法
  7. 获取微软原版“Windows 10 推送器(GWX)” 卸载工具
  8. 朗润国际期货:上海期货交易所仓单日报
  9. 传递函数波特图的画法和理解(2)
  10. 11-【数据库】定义表结构的时间字段的两种方式