测试覆盖率

基本概念

覆盖率是度量测试完整性的一个手段,是测试有效性的一个度量。

评测方法

测试覆盖是对测试完全程度的评测,它建立在测试覆盖基础上,测试覆盖是由测试需求和 测试用例的覆盖或已执行代码的覆盖表示的。
质量是对测试对象(系统或测试的 应用程序)的可靠性、稳定性以及性能的评测。质量建立在对测试结果的评估和对测试过程中确定的变更请求(缺陷)的分析的基础上。

覆盖评测

两种评测

覆盖指标提供了"测试的完全程度如何"这一问题的答案,最常用的覆盖评测是基于需求的测试覆盖和基于代码的测试覆盖。简而言之,测试覆盖是就需求(基于需求的)或 代码的设计/实施标准(基于代码的)而言的完全程度的任意评测,如 用例的核实(基于需求的)或所有代码行的执行(基于代码的)。
系统的测试活动建立在至少一个测试覆盖策略基础上。覆盖策略陈述测试的一般目的,指导测试用例的设计。覆盖策略的陈述可以简单到只说明核实所有性能。
如果需求已经完全分类,则基于 需求的覆盖策略可能足以生成测试完全程度的可计量评测。例如,如果已经确定了所有性能测试需求,则可以引用测试结果来得到评测,如已经核实了 75% 的性能测试需求。
如果应用基于代码的覆盖,则测试策略是根据测试已经执行的 源代码的多少来表示的。这种测试覆盖策略类型对于安全至上的系统来说非常重要。

两种评测方法

两种评测都可以手工得到(公式如下所示)或通过测试自动化工具计算得到。
基于需求的测试覆盖
基于需求的测试覆盖在测试生命周期中要评测多次,并在测试生命周期的里程碑处提供测试覆盖的标识(如已计划的、已实施的、已执行的和成功的测试覆盖)。
在执行测试活动中,使用两个测试覆盖评测,一个确定通过执行测试获得的测试覆盖,另一个确定成功的测试覆盖(即执行时未出现失败的测试,如没有出现缺陷或意外结果的测试)。
基于代码的测试覆盖
基于代码的测试覆盖评测测试过程中已经执行的代码的多少,与之相对的是要执行的剩余代码的多少。代码覆盖可以建立在控制流(语句、分支或路径)或数据流的基础上。控制流覆盖的目的是测试代码行、分支条件、代码中的路径或 软件控制流的其他元素。数据流覆盖的目的是通过软件操作测试数据状态是否有效,例如,数据元素在使用之前是否已作定义。
覆盖率等于覆盖面积/总面积

覆盖率准则

为了量测 测试套件测试软件的程度,会用一种或多种不同的覆盖率准则。 [1]

基本的覆盖率准则

以下列出一些基本的覆盖率准则:
  • 函式覆盖率(Function coverage):有呼叫到程式中的每一个函式(或副程式)吗?
  • 指令覆盖率(Statement coverage):若用 控制流图英语:control flow graph)表示程式,有执行到控制流图中的每一个节点吗?
  • 判断覆盖率(Decision coverage):(和分支覆盖率不同)若用控制流图表示程式,有执行到控制流图中的每一个边吗?例如控制结构中所有IF指令都有执行到逻辑运算式成立及不成立的情形吗?
  • 条件覆盖率(Condition coverage):也称为谓词覆盖(predicate coverage),每一个逻辑运算式中的每一个条件(无法再分解的逻辑运算式)是否都有执行到成立及不成立的情形吗?条件覆盖率成立不表示判断覆盖率一定成立。
  • 条件/判断覆盖率(Condition/decision coverage):需同时满足判断覆盖率和条件覆盖率。
考虑以下的C++函式:
intfoo(intx,inty){intz=0;if((x>0)&&(y>0)){z=x;}returnz;}
假设此函式是一个大型程式的一部份,且某测试用例执行到此函式:
  • 函式覆盖率:只要函式foo有执行过一次,即满足函式覆盖率100%的条件。
  • 指令覆盖率:若有呼叫过foo(1,1),函式中每一行(包括z = x;)都执行一次,满足指令覆盖率100%的条件。
  • 判断覆盖率:若有呼叫过foo(1,1)及foo(0,1),前者会使if的条件成立,因此z = x;会执行,后者会使if的逻辑运算式((x>0) && (y>0);)不成立,因此满足判断覆盖率100%的条件。
  • 条件覆盖率:若有呼叫过foo(1,1)、foo(1,0)及foo(0,0),前二个会使(x>0)的条件成立,而第三个会使该条件不成立,而第一个会使(y>0)的条件成立,而后面二个会使该条件不成立,所有条件都有出现成立及不成立的情形,因此满足条件覆盖率100%的条件。
考虑以下的程式:
ifaandb then
以下二个测试可以得到100%的条件覆盖率:
  • a=true,b=false
  • a=false,b=true
但上述的测试条件都不会使if的逻辑运算式成立,因此不符合判断覆盖的条件。
有时会需要用错误插入( 英语:Fault injection)的方式来确保所有条件及 异常处理程式都有一定的覆盖率。

修改条件/判断覆盖

在一些安全关键应用(例如飞航用的软件)中,一般会需要满足修改条件/判断覆盖(modified condition/decision coverage,简称MC/DC)的准则。此准则是条件/判断覆盖的延伸,而且每个条件都要可以独立影响判断结果的成立或不成立。例如考虑以下的程式:
if(a orb)andc 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
其中粗体的条件表示是会影响判断结果的条件,在影响判断结果的条件中,每个变量都出现至少二次,其中至少一次其值为真,至少一次其值为假。

多重条件覆盖

此覆盖率准则要求要测试逻辑运算式中的所有组合,例如上述程式的多重条件覆盖需要有以下的8个测试:
  • a=false, b=false, c=false
  • a=false, b=false, c=true
  • a=false, b=true, c=false
  • a=false, b=true, c=true
  • a=true, b=false, c=false
  • a=true, b=false, c=true
  • a=true, b=true, c=false
  • a=true, b=true, c=true

其他覆盖率准则

以下也是一些可能会用到的覆盖率准则:
  • JCSAJ覆盖率:是否执行过每一个JCSAJ(线性代码序列和跳转)?
  • JJ路径覆盖率(JJ-Path coverage):是否执行过每一个JJ路径(从跳转到跳转之间的路径,也就是JCSAJ)?
  • 路径覆盖率(Path coverage):是否执行过程式中所有可能的路径?
  • 进入点/结束点覆盖率(Entry/exit coverage) :是否执行过函式中所有可能的进入点及结束点?
  • 循环覆盖率(Loop coverage):所有循环是否都有执行过零次、一次及一次以上的测试?
  • 参数值覆盖率(Parameter Value Coverage):对于一个方法的所有参数,是否有执行过其中最常见的数值?
安全关键应用一般会要求某种特定的覆盖率要到达100%。
有些覆盖之间有相关性:例如路径覆盖就包括了判断覆盖、指令覆盖及进入点/结束点覆盖,而判断覆盖也包括了指令覆盖。
完整的路径覆盖测试多半难以实现甚至不可能实现。有个判断的程式就会有种完整路径,循环结构可能会产生无穷种完整路径。程式中的许多路径也许是不可行的,因为也许没有受测系统的输入,使系统完整依某特定路径执行。而且已证实没有识别不可行路径的通用算法(若有,此算法就可以求解 停机问题)。实务上路径覆盖测试的软件只会试图找出随着循环执行次数不同时,有变动的路径,设法找到“基本路径”,并要求对基本路径需达到路径覆盖的要求。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值