上篇文章,介绍了软件测试相关的基础概念,其中白盒测试中的逻辑覆盖率知识点比较复杂,本篇通过实例来讲解各种覆盖率的测试用例该如何设计。

1 基础示例

1.1 例题一

有如下程序,设计分别满足语句覆盖分支覆盖的最有效力的测试用例。

int x = 0;
int y = 0;

if (x > 0 && y > 0)
{
    y = y/x;
}

if (x > 1 || y > 1)
{
    y = y + 1;
}

x = x + y;

分析:

语句覆盖只需要所有的语句都被执行过即可,针对此程序,只需要使两个if语句都为true即可,例如x=2,y=0。

分支覆盖,也叫判定覆盖,只需要所有的判断都能取到所有可能的值即可,针对此程序,只需要使两个if语句各自都取到true和false即可,例如x=2,y=0(两个if都是true); x=0,y=0(两个if都是false)需要两条用例。

1.2 例题二

有如下程序,变量i取什么值能效力最高的满足判断覆盖?

void main()
{
    int i = 0;
    int sum = 0;
    scanf("%d", &i);
    while(i <= 10)
    {
        sum += i;
        i++;
    }
    printf("%d\n", sum);
}

分析:

此程序中,while语句是路径分支。效力最高的满足判断覆盖,即在最小的循环执行次数下,判断可以取到true和false。因此,取i=10,满足true,下一轮循环i变为了11,满足false。

1.3 例题三

有如下程序,满足判定覆盖至少需要几条测试用例?

int func(int n)
 {
     if (n == 0)
     {
         return 33;
     }
     
     if (n == 1)
     {
         return 66;
     }
     
     if (n > 1)
     {
         return func(n - 1) + func(n - 2) + func(n - 3) ;
     }
     else
     {
         return 99;
     }
 }

分析:

此程序中,2个if和1个if-else组成了所有的判断,满足判定覆盖,即需要让所有的判定各取true和false。最简单直观的是用4条用例n=0; n=1; n=2; n=-1即可满足,注意到程序里有递归调用,实际上取n=2,会调用return func(1) + func(0) + func(-1) ;即可满足。

2 进阶示例

有如下程序,设计各种逻辑覆盖的测试用例:

int test (int x, int y)
{
    int ret = 0;
    if (x > 0 && y > 0)
    {
        ret = x + y + 10; //语句块1
    }
    else
    {
        ret = x + y - 10; //语句块2
    }
    
    if (ret < 0)
    {
        ret = 0; //语句块3
    }
    
    return ret; //语句块4
}

分析:根据程序,先画出流程图:

嵌入式基础知识-逻辑覆盖测试用例设计_条件判定覆盖C/DC

2.1 语句覆盖SC

设计满足语句覆盖(SC)的测试用例,即运行完测试用例,能将程序中每条可执行语句至少被执行一次。

本例中,就是要把语句块1~语句块4都执行一遍。

用例数据

语句块1

语句块2

语句块3

语句块4

{x=3, y=3}


-

abef


{x=-3, y=0}

False




嵌入式基础知识-逻辑覆盖测试用例设计_条件判定覆盖C/DC_02

2.2 判定覆盖DC

设计满足判定覆盖(DC)的测试用例,即运行完测试用例,使得程序中每个判断的True和False分支至少被执行一次。

判定覆盖,也叫分支覆盖

用例数据

P1(x>0&&y>0)

P2(ret<0)

{x=3, y=3}

True

False

{x=-3, y=0}

False

True

嵌入式基础知识-逻辑覆盖测试用例设计_语句覆盖SC_03

2.3 条件覆盖CC

设计满足条件覆盖(CC)的测试用例,即运行完测试用例,使得程序中每个逻辑条件的可能值至少被满足一次。

用例数据

C1(x>0)

C2(y>0)

C3(ret<0)

P1(x>0&&y>0)

P2(ret<0)

{x=3, y=0}

True

False

True

False

True

{x=-3, y=15}

False

True

False

False

False

嵌入式基础知识-逻辑覆盖测试用例设计_语句覆盖SC_04

2.4 条件判定覆盖C/DC

设计满足条件判定覆盖(C/DC)的测试用例,即运行完测试用例,使得程序中每个判断的True和False分支至少被执行一次,同时,使得程序中每个逻辑条件的可能值至少被满足一次。

用例数据

C1(x>0)

C2(y>0)

C3(ret<0)

P1(x>0&&y>0)

P2(ret<0)

{x=3, y=3}

True

True

False

True

False

{x=-3, y=0}

False

False

True

False

True

嵌入式基础知识-逻辑覆盖测试用例设计_条件判定覆盖C/DC_05

2.5 条件组合覆盖MCC

设计满足组合覆盖(MCC)的测试用例,即运行完测试用例,使得程序中每个判断的所有可能条件取值的组合至少被满足一次。

注意几点:

  • 条件组合只针对同一个判断语句内存在多个条件的情况
  • 不同的判断语句内的条件直接无需组合
  • 对于单条件的判断语句,只需满足自己的所有取值即可

用例数据

C1(x>0)

C2(y>0)

C3(ret<0)

P1(x>0&&y>0)

P2(ret<0)

路径

{x=-3, y=0}

False

False

True

False

True

acdf

{x=-3, y=2}

False

True

True

False

True

acdf

{x=3, y=0}

True

False

True

False

True

acdf

{x=3, y=3}

True

True

False

True

False

abef

嵌入式基础知识-逻辑覆盖测试用例设计_条件判定覆盖C/DC_06

2.6 路径覆盖PC

设计满足路径覆盖(PC)的测试用例,即运行完测试用例,使得程序中每条路径至少被覆盖一次。

用例数据

C1(x>0)

C2(y>0)

C3(ret<0)

P1(x>0&&y>0)

P2(ret<0)

路径

不可能路径

-

-

-

-

-

abdf

{x=0, y=2}

False

True

True

False

True

acdf

{x=3, y=5}

True

True

True

True

True

abef

{x=-10, y=30}

False

True

False

False

False

acef

嵌入式基础知识-逻辑覆盖测试用例设计_条件覆盖CC_07

3 修正的条件判定覆盖MC/DC

修正的条件判定覆盖MC/DC,这里再描述一下含义:

MC/DC要求设计适当数量的测试用例,满足以下条件:

  • 保证在一个程序中每一种输入输出至少出现一次
  • 在程序中的每一个条件必须产生所有可能的输出结果至少一次
  • 并且每个判断中的每个条件必须能独立影响一个判断的输出(即在其它条件不变的前提下,仅改变这个条件的值,而使判断结果改变)

有如下程序,若要满足修正的条件判定覆盖,最少的测试用例需要几条:

bool func(bool x, bool y, bool z)
{
    if (x && (y || z))
    {
        return true;
    }
    
    return false;
}

先画出流程图,这里给出两种画法:

嵌入式基础知识-逻辑覆盖测试用例设计_语句覆盖SC_08

对于修正的条件判定覆盖:

  • 首先需要先进行条件组合,本例中P1判定内包含3个布尔值的条件x、y、z,对其组合有8种情况
  • 然后再分别对每个条件的用例进行计算,规则为:
  • 条件Cx所在的判定内(本例即P1),除条件Cx外,其它条件的取值完全相同(例如对于C1,就是找到与x的值相反,y和z相同的用例 )
  • 判定的结果与之相反(例如对于C1,用例2和用例6的判定结果就是相反的)

按照以上规则,可以得到如下表:

嵌入式基础知识-逻辑覆盖测试用例设计_语句覆盖SC_09

观察表格:

  • 对于条件z,需要选用用例5和6
  • 对于条件y,需要选用用例5和7
  • 对于条件x,需要选用用例2和6,或用例3和7,或用例2和8

为了实现最少的用例能满足MC/DC,可选的用例组合为:

  • 组合1:用例2、用例5、用例6、用例7
  • 组合2:用例3、用例5、用例6、用例7

即最少需要4条用例才能满足MC/DC。

例如选择组合1,将冗余的用例去除,得到如下表:

嵌入式基础知识-逻辑覆盖测试用例设计_条件覆盖CC_10

再来分析一次:

  • 对于条件x,使用用例2和6来测试,y和z的值相同(y=0,z=1),P1判定结果刚好是不同值(0和1)
  • 对于条件y,使用用例5和7来测试,x和z的值相同(x=1,z=0),P1判定结果刚好是不同值(0和1)
  • 对于条件z,使用用例5和6来测试,x和y的值相同(x=1,y=0),P1判定结果刚好是不同值(0和1)

最后,再来通过在流程图上标注来对比看下,加深理解:

嵌入式基础知识-逻辑覆盖测试用例设计_条件判定覆盖C/DC_11

4 总结

本篇介绍了软件测试中,白盒测试中逻辑覆盖的各种实例情况,包括语句覆盖SC、判定覆盖DC、条件覆盖CC、条件判定覆盖C/DC、条件组合覆盖MCC、路径覆盖PC、修正的条件判定覆盖MC/DC的实例。