分享

C0、C1、C2は何?

 men_darling 2018-03-04


有人说是驾照(准备考驾照的帅哥哥),

有人说是铁路信号系统(高铁上的漂亮姐姐),

还有人说是钢琴谱的八度(正在学钢琴的女儿),

更有高人说是曲线光顺度量(邻家大博士)(好深奥)。。。

没想到会有这么多种答案,涨姿势(长知识)了。


那作为一个程序员,今天想跟大家谈的C0、C1、C2是什么呢?IT软件同行,可能大部分已经猜得八九不离十了。对的,代码覆盖率(Code Coverage)。在我们软件开发这行,除了做设计,写代码,还有更重要的一项工作,就是测试。设计做得再完美,代码写得多激情澎湃,不静下心来老老实实地做一下测试,即便拥有几十年开发经验的资深程序员也不敢拍着胸脯保证自己的代码没有bug,100%正确。软件测试是软件开发工程中不可缺少的重要一步。那如何做好软件测试,如何评价一个软件测试是否有效、完整程度如何呢?代码覆盖率就这样应运而生,它是对测试完整程度的一个量化描述,是测试效率状况的一个很有价值的参考指标。可以肯定地说,它是各位行业前辈的智慧的结晶啊(膜拜)。扯了这么些,回归本题,接下来结合下面的流程图来具体介绍一下C0、C1、C2,以及在实际工作中其它几种比较常用的覆盖率准则。掌握这些基准,相信你的单体case不会再犯难,工期紧任务重的时候,可以有的放矢有效删减case。在和客户侃大山时,也给自己长涨姿势(龇牙)。


※天外有天,人外有人。各位大侠,走过路过瞧瞧。欢迎批评指正。(敬请赐教)


                             【程序流程图】



1.语句覆盖(Statement Coverage)【C0】


【概念】 设计测试case,能使程序中每个可执行语句至少执行一次。又称行覆盖(Line Coverage),段覆盖(Segment Coverage),基本块覆盖(Basic Block Coverage)。


【优点】 可以很直观地从源代码得到测试用例(case),无须细分每条分支判定表达式。是最常用也是最简单的一种覆盖指标。在上面的程序流程图里,语句1、2、3、4都至少被执行一次,则C0覆盖即为100%。


【缺点】 仅仅针对程序逻辑中显式存在的语句,对于隐藏的条件,比如对一些控制结构的代码而言,它不能真正表示是否完全覆盖到。素有最弱覆盖之称,可以说,是软件测试所要达到的最低指标吧。例如上面流程图中,[条件1]=false的场合,没有显式存在的语句需要执行,按照语句覆盖的原则,这个逻辑分支即便不设定case,也不影响语句覆盖率高低。这点在实际作业中要注意。此外,还有一些特殊处理,若单纯依据语句覆盖准则,也可能会造成case遗漏,bug检知不能。举个简单的例子。


    int divided(int a, int b){

       return a / b;

    }

上面的代码可执行语句只有一句:a除以b的商。任一组a和b的值便可以使语句覆盖率达到100%。但是b=0的时候,很明显程序会出bug。如果这个case没有设定,你可能就成本番障的害罪魁祸首,要被深掘的噢(捂嘴)。实际作业中,最好不要单纯以语句覆盖基准来做测试case和测试评价。把它当作检知未测试代码的最快捷的一种手段更好。要想做好测试case,通常都需要掌握多种覆盖率基准,组合运用。打拳要出组合拳,你才最厉害。一个道理的。其它覆盖率基准咱们接着往下走着。


2.判定覆盖(Decision Coverage)【C1】


【概念】 设计测试case,能使得程序中每个分支判定的bool(布尔)表达式在false和true的条件下,至少各被执行一次。即判断真假值均曾被满足一次。又称分支覆盖(Branch Coverage)。


【优点】 判定覆盖具有比语句覆盖更强的测试能力。同样判定覆盖也具有和语句覆盖一样的简单性,无须细分每个分支判定的条件,只需按照判定的结果,true的分支和false的分支就可以得到测试用例(case)。在上面的流程图中,条件1的true的分支和false的分支,以及条件2的true的分支和false的分支,都至少被执行一次的话,C1覆盖即为100%。前面说语句覆盖的时候,说过[条件1]=false的场合可能会遗漏case。但如果按照判定覆盖基准来设计case,这个case就不会漏掉了。所以,组合拳还是很厉害的噢。


【缺点】 往往大部分分支判定的bool表达式语句是由多个逻辑条件组合而成,若仅仅判断其整个最终结果,而忽略每个条件的取值情况,必然会遗漏部分测试路径。判定覆盖仍是比较弱的逻辑覆盖。在前面的程序流程图中,如果[条件1]的bool表达式是这样:


a && (b || c)


很明显只测bool表达式的true和false两种分支case是不足的。内部的各个逻辑条件a、b、c,也是我们实际作业中需要关注,着重去测试的。这就是接下来的条件覆盖。


3.条件覆盖(Condition Coverage)【C2】


【概念】设计测试case,能使每个最小单位的逻辑条件取得true和false的值,至少一次。注意,不包括各个逻辑条件true和false的排列组合。只是各取得一次true和false的值就可以。


【优点】增加了对各个逻辑条件判定情况的测试,与判定覆盖相比,增加了测试路径。已经属于软件测试中比较强的覆盖了。


【缺点】条件覆盖不一定包含判定覆盖。条件覆盖只能保证每个条件至少有一次为真,而不考虑所有的判定结果。例如对于bool表达式:


a || b


来说,下面的case1和case2,因为a和b的true、false的值都覆盖到了,C2条件覆盖率就达到了100%。但是无论是case1还是case2,条件(a || b)的判定结果都是true,测试路径都是真值这个分支,也就是所说上面讲过的C1分支覆盖率都没有达到100%。


Case1: a = true, b = false

Case2: a = false, b = true


    到这里可以看出,C0、C1、C2有如下关系:


 


上图可以看出,任何一种覆盖率基准都不能覆盖程序的所有逻辑,只有同时运用多种基准,才能增大覆盖面积,以提高代码测试覆盖率。所以,重要的事情说第三遍。尽可能掌握多种覆盖基准,在实际的测试用例设计过程中,根据需要将不同的覆盖方法组合起来使用,以实现最佳的测试case。C0、C1、C2,是软件测试中最基本的三种覆盖率基准,到此就介绍完毕了。接下来简单介绍一些实际作业中比较常用的其它几种。


4.判定/条件覆盖(Decision/Condition Coverage)


【概念】 设计测试case,能使得判断条件中的所有条件可能至少执行一次取值,同时,所有判断的可能结果至少执行一次。


【优点】能同时满足判定、条件两种覆盖标准。


【缺点】判定/条件覆盖准则的缺点是未考虑条件的组合情况。


【举例】以前面讲C2条件覆盖时所举例子为例,咱们一起来看,如何设计case使得判定/条件覆盖率达到100%。


a || b


对于上述条件,我们首先沿用前面C2条件覆盖时所设计的测试case,来使它满足C2覆盖率100%。


Case1: a = true, b = false     ⇒判定结果:true

Case2: a = false, b = true     ⇒判定结果:true


然后,我们再追加下记case,使之再满足C1判定覆盖100%,那我们的目的就达到了。


Case3: a = false, b = false    ⇒判定结果:false


综上,通过测试Case1,2,3,我们终于可以使条件(a || b)的判定/条件覆盖率达到100%了。同时,C1判定覆盖率为100%,C2条件覆盖率也为100%。把判定/条件覆盖加到前面的覆盖率关系图里就可以这样表达:


判定/条件覆盖基准,个人的项目经验分享一下,它是对条件判定处理的有效path进行的针对性测试,对此类处理的bug检出率很高。在做测试case时,基本是必用准则之一。重点掌握。


5. 条件组合覆盖(Multiple Condition Coverage)


【概念】设计测试case,能使得所有可能的条件取值组合至少执行一次。


【优点】条件组合覆盖准则满足判定覆盖、条件覆盖和判定/条件覆盖准则。把它加到前面的关系图里,可以这样表述。

 


【缺点】线性地增加了测试用例的数量。每增加一个条件就要多一个阶乘。借前面提到的两个例子一起来看一下。


例1:

a || b


条件组合覆盖率100%的测试case有四个。、


Case1: a = true, b = false     ⇒判定结果:true

Case2: a = false, b = true     ⇒判定结果:true

Case3: a = false, b = false    ⇒判定结果:false

Case4: a = true, b = false     ⇒判定结果:true


例2:

a && (b || c)


比[例1]判定条件增加一个,条件组合覆盖率100%的测试case则要多达8个。


Case1: a = true, b = true, c = true     ⇒判定结果:true

Case2: a = true, b = true, c = false    ⇒判定结果:true

Case3: a = true, b = false, c = true    ⇒判定结果:true

Case4: a = true, b = false, c = false   ⇒判定结果:false

Case5: a = false, b = true, c = true    ⇒判定结果:false

Case6: a = false, b = true, c = false   ⇒判定结果:false

Case7: a = false, b = false, c = true   ⇒判定结果:false

Case8: a = false, b = false, c = false  ⇒判定结果:false


 在此,明确阐述一个观点。虽然一直在说某某某代码覆盖率100%,但并不是要强调测试就一定要达到代码覆盖率100%。代码覆盖率,正如开篇所言,它是对测试完整程度的一个量化描述,是测试效率状况的一个参考指标。测定代码覆盖率的意义在于,分析未覆盖部分的代码,从而反推在前期测试设计是否充分,没有覆盖到的代码是否是测试设计的盲点,为什么没有考虑到?需求/设计不够清晰,测试设计的理解有误,工程方法应用后的造成的策略性放弃等等,之后进行补充测试用例设计。同时,还可以检测出程序中的废代码,可以逆向反推在代码设计中思维混乱点,提醒设计/开发人员理清代码逻辑关系,提升代码质量。代码覆盖率高不能说明代码质量高,但是反过来看,代码覆盖率低,代码质量不会高到哪里去,可以作为测试自我审视的重要工具之一。而各个覆盖率基准具体指导我们怎么去考虑case。实际开发作业中,通常测试时间非常紧张。往往需要在短时间内完成有质量有效率的测试。单纯按照条件组合覆盖基准来设计case,势必测试量会很大。可不可以精简case呢?我们结合上面的例2来分析一下。如果开发语言是C、JAVA等高级语言,那么对于条件:a && (b || c)来说,当a = false的时候,判定结果就会返回false,而不会继续判定后面的b和c的值。从这点上来说,case5到case8是等同case,从中选取一个来测即可。通过这种方法,可以去掉一些无效测试案例。筛检有效案例的另外一个方法,咱们在下面的路径覆盖再说。


6.路径覆盖(Path Coverage)


【概念】设计测试case,覆盖程序中的所有可能的执行路径 。又称断言覆盖(Predicate Coverage)


【优点】 这种测试方法可以对程序进行彻底的测试,比前面五种的覆盖面都广。被称为最强覆盖。


【缺点】 需要设计大量、复杂的测试用例,使得工作量呈指数级增长,不见得把所有的条件组合都覆盖。做到路径全覆盖,实践起来其实很困难。通常在实际作业中,根据实际可能发生的数据variation,来测试所有可能执行的程序路径。这样也可以达到筛检有效case的目的。


以上介绍的覆盖率基准,都属于单体测试的白盒测试的逻辑覆盖范围。除此以外,像函数覆盖((Function Coverage)执行到每一个函数)、循环覆盖((Loop Coverage)是否对循环体执行了零次、一次和多余一次)等等,大家都比较熟悉,在这里就不一一介绍了。还有,单体测试的另一种手段,黑盒测试做case设计时,用到的等价类划分法(日语:同值分割)和边界值分析法(日语:境界值分析),此次由于篇幅的原因也不介绍了。有兴趣朋友,可以查一下百度百科或维基百科的同名词条,讲的还是很清晰易懂的。或者给我留言,下期咱接着聊(开心)。

最后,把单体测试中常用的一些覆盖率基准列了张表,有个完整的印象。


单体覆盖率

覆盖率基准

白盒覆盖

 

语句覆盖(Statement Coverage)

【C0】

判定覆盖(Decision Coverage)

【C1】

条件覆盖(Condition Coverage)

【C2】

判定/条件覆盖

(Decision/Condition Coverage)

条件组合覆盖

(Multiple Condition Coverage)

路径覆盖(Path Coverage)

其他覆盖

  函数覆盖率(function coverage)

  调用覆盖率(call coverage)

  接口覆盖(Interface Coverage)

  循环覆盖率(loop coverage)

  ······

黑盒覆盖

同値分割(Equivalence Partitioning)

限界値分析(境界値分析)

(Boundary Value Analysis)


本文作成过程中,参看学习了下记网络资料。

1:维基百科,词条:代码覆盖率

2:百度百科,词条:代码覆盖测试、覆盖率

3:猫でも分かるソフトウェアのテスト網羅

4:ソフトウェアの検証の種類



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多