微信号:TesterTalk

介绍:专注软件测试技术分享,包括不限于Web 测试,Mobile测试,API测试,自动化测试,性能测试知识/方法, 以及软件测试职位推荐.

白盒测试之逻辑覆盖法

2016-06-08 19:04 摘自网络

点击标题下「蓝色微信名」可快速关注

逻辑覆盖是以程序内部的逻辑结构为基础的设计测试用例的技术。


根据覆盖目标的不同和覆盖源程序语句的详尽程度,逻辑覆盖又可分为:


1. 语句覆盖(SC)

2. 判定覆盖(DC)

3. 条件覆盖(CC)

4. 条件/判定覆盖(CC)

5. 条件组合覆盖(MCC)

6. 修正判定条件覆盖(MCDC)

7. 点覆盖

8. 边覆盖

9. 路径覆盖


几种逻辑覆盖标准发现错误的能力呈由弱至强的变化。


下面我们来逐一举例详解:


1
语句覆盖(SC):

语句覆盖是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每一个语句至少执行一次,其覆盖标准无法发现判定中逻辑运算的错误.


我们看下面的被测试代码:

int foo(int a, int b)

{

return a / b;

}

假如我们的测试人员编写如下测试案例:

TeseCase: a = 10, b = 5


测试人员的测试结果会告诉你,他的代码覆盖率达到了100%,并且所有测试案例都通过了。然而遗憾的是,我们的语句覆盖率达到了所谓的100%,但是却没有发现最简单的 Bug,比如,当我让b=0时,会抛出一个除零异常。


简言之,语句覆盖,就是设计若干个测试用例,运行被测程序,使得每一可执行语句至少执行一次。这里的“若干个”,意味着使用测试用例越少越好。


语句覆盖率的公式可以表示如下:

语句覆盖率=可执行的语句总数/被评价到的语句数量 x 100%

2
判定覆盖(DC)

判定覆盖是设计足够多的测试用例,使得程序中的每一个判断至少获得一次“真”和一次“假”,即使得程序流程图中的每一个真假分支至少被执行一次。

但若程序中的判定是有几个条件联合构成时,它未必能发现每个条件的错误。


例:

int a,b;

if(a || b)

执行语句1

else

执行语句2


要达到这段程序的判断覆盖,我们采用测试用例:

1)a = true , b = false;

2)a = false, b = false

3
条件覆盖(CC)

条件覆盖是指选择足够的测试用例,使得运行这些测试用例时,判定中每个条件的所有可能结果至少出现一次,但未必能覆盖全部分支.

例:

int a,b;

if(a || b)

执行语句1

else

执行语句2


要达到这段程序的条件覆盖,我们采用测试用例:

1)a = true , b = false ;

2)a = false, b = true

4
判定/条件覆盖(CDC

判定/条件覆盖是使判定中每个条件的所有可能结果至少出现一次,并且每个判定本身的所有可能结果也至少出现一次。

例:

int a,b;

if(a || b)

执行语句1

else

执行语句2


要达到这段程序的判定/条件覆盖,我们采用测试用例:

1)a = true , b = true;

2)a = false, b = false

5
条件组合覆盖(MCC)

选择足够的测试用例,使得每个判定中条件的各种可能组合都至少出现一次。显然,满足“条件组合覆盖”的测试用例是一定满足“判定覆盖”、“条件覆盖”和“判定/条件覆盖”的。


例:

int a,b;

if(a || b)

执行语句1

else

执行语句2


要达到这段程序的判定/条件覆盖,我们采用测试用例:

1)a = true , b = true;

2)a = false, b = false

3)a = true,  b = false

4)a = false,  b = ture

6
修正判定条件覆盖(MC/DC)

MC/DC首先要求实现条件覆盖、判定覆盖,在此基础上,对于每一个条件C,要求存在符合以下条件的两次计算:
    1)条件C所在判定内的所有条件,除条件C外,其他条件的取值完全相同;
    2)条件C的取值相反;
    3)判定的计算结果相反。

    核心意思是每个条件都要独立影响判定结果。为什么说“两次计算”,而不是“两个用例”呢?当循环中有判定时,一个用例下同一判定可能被计算多次,每次的条件值和判定值也可能不同,因此,一个用例就可能完成循环中判定的MC/DC。

    MC/DC是条件组合覆盖的子集。条件组合覆盖要求覆盖判定中所有条件取值的所有可能组合,需要大量的测试用例,实用性较差。MC/DC具有条件组合覆盖的优势,同时大幅减少用例数。满足MC/DC的用例数下界为条件数+1,上界为条件数的两倍,例如,判定中有三个条件,条件组合覆盖需要8个用例,而MC/DC需要的用例数为4至6个。如果判定中条件很多,用例数的差别将非常大,例如,判定中有10个条件,条件组合覆盖需要1024个用例,而MC/DC只需要11至20个用例。

    下面是MC/DC的示例:

    代码:
    int func(BOOL A, BOOL B, BOOL C)
    {
        if(A && (B || C))
            return 1;
        return 0;
    }

    用例:


    对于条件A,用例1和用例2,A取值相反,B和C相同,判定结果分别为1和0;
    对于条件B,用例1和用例3,B取值相反,A和C相同,判定结果分别为1和0;
    对于条件C,用例3和用例4,C取值相反,A和B相同,判定结果分别为0和1。

9
路径覆盖(PC)

MC/DC被称为“最严格的标准”,但这种说法是将条件组合覆盖和路径覆盖排除在外为基础的。MC/DC显然不如条件组合覆盖严格,但是条件组合覆盖需要太多用例,实际应用中难以做到,所以排除,那么,路径覆盖是否也难以做到?使用先进的工具,对于一般的代码,实现路径覆盖还是可能的。另外,路径代表了从函数入口到出口的所有可能的代码组合,这些组合会不会出问题?只有路径覆盖能发现,这与MC/DC侧重于判定内的条件的组合关系是完全不同的。

    MC/DC与路径覆盖的侧重点不同,两者都有其优势和局限性,如果组合起来,优势互补,形成“MC/DC-路径覆盖”,就是真正意义上的“最严格的标准”了。

    有些程序,路径数量可能大得惊人,可用以下规则和方法减少路径数量:
    计算路径时,不考虑循环的次数,将循环结构视为循环体“至少执行一次”和“从不执行”两个分支;
    不考虑条件的计算结果只考虑判定的计算结果,条件间的组合关系由条件覆盖、C/DC和MC/DC负责;
    一个分支如果不可达,通过该分支的所有路径也不可达,可以让工具自动排除;
    当代码很复杂时,理想的处置方式是将部分代码独立为函数,如果做不到,可以让工具来模拟,即在逻辑结构图中,将部分代码临时屏蔽,被屏蔽的代码视为一个函数调用。交替屏蔽可以既减少路径数量,又保证路径覆盖的效果。

    对于一般复杂度的代码,采用以上规则和方法后,路径数量和用例数量可以维持在一个现实可覆盖的的范围内。

    路径覆盖的主要缺陷是:不相关的逻辑块会组合出大量没有意义的路径。一个函数的路径,可能达到几万条甚至几百万条。如果路径超过100条,通常路径覆盖就没有意义了。对于一般企业来说,建议用MC/DC作为统一的覆盖标准,只有特别关键的代码
才要求完成“MC/DC-路径覆盖”


路径覆盖要求设计足够多的测试用例,在白盒测试法中,覆盖程度最高的就是路径覆盖,因为其覆盖程序中所有可能的路径。

对于比较简单的小程序来说,实现路径覆盖是可能的,但是如果程序中出现了多个判断和多个循环,可能的路径数目将会急剧增长,以致实现路径覆盖是几乎不可能的。





关于iTesting

欢迎关注 iTesting. 
iTesting致力于软件测试技术分享, 包括不限于 Web测试, Mobile测试, API测试, 性能测试以及测试职位推荐.


长按下图二维码,在弹出菜单中选择“识别图中二维码”关注本公众号.


更多内容,敬请期待


 
iTesting 更多文章 测试的原则 等价类划分 边界值分析 因果图法 正交试验法
猜您喜欢 有了这样的编程学习工具,再学不好,就是你不努力了! MoboMarket流量性能提升测试分析 【重磅】微信开源PhxSQL:高可用、强一致的MySQL集群 用DevOps开发DevOps实战 | 在线技术公开课 Docker - 原理,技巧与使用指南