碎片 发表于 2007-7-22 13:30:06

关于覆盖率的大疑问---条件覆盖率

问题:
1.什么是覆盖率?
2.覆盖率到底是干什么的?
3.覆盖率检测是在什么时候进行的?
4.覆盖率检测到底要不要执行程序?



if (a>1 and b=0)
x=x/a;
if (a=2 or x>1)
x=x+1;

针对上面的程序段,进行条件覆盖率检测

条件   真   假   
a>1   T1   F1
b=0   T2   F2
a=2   T3   F3
x>1   T4   F4

         a    b    x
case1:1    0    3    F1 T2 F3 T4
case2:2    1    1    T1 F2 T3 F4   

找了好多资料,都是以这道题为例,根据上面结果得出来的条件覆盖率都是100%,得出这个结果是根据条件与用例值,并不执行测试用例与程序。
如果根据用例执行程序的话,得出的 case1:F1 F3       case2:T1 T3   覆盖率是50%

很迷糊,回到顶上的问题,大家帮忙分析一下。

ivyhuan 发表于 2007-7-22 15:20:48

1.覆盖率是用来度量测试完整性的一个手段。
2.覆盖率是测试技术有效性的一个度量。
3.覆盖率有单元测试时的逻辑覆盖率;
               集成测试时的接口覆盖率;
               系统测试时的需求覆盖率;各个阶段都有
   以你的这个条件覆盖应属于单元测试的
4.覆盖检测一般是要执行程序的

a    b    x
case1:1    0    3    F1 T2 F3 T4
case2:2    1    1    T1 F2 T3 F4   
因为八个条件都覆盖到了,所以覆盖率为100%

“如果根据用例执行程序的话,得出的 case1:F1 F3       case2:T1 T3   覆盖率是50%”

程序执行了a>1也肯定执行了b=0,他们属于一个语句里的,用括号包起来的
所以都判断了
除非有break强制退出的,才不执行后面的语句。
我是这么认为的

碎片 发表于 2007-7-22 17:36:18

回复 #2 ivyhuan 的帖子

如果覆盖率是在程序执行之后得到了,那个像上面的例子中,and和or在程序执行过程中是会出现短路现象的。

当and前的条件不满足是,程是不对后面的条件进行判断的,同样,在or前面的条件满足是,也不会对后面的条件进行判断.

碎片 发表于 2007-7-22 17:44:35

回复 #1 碎片 的帖子

那么下面这道题的条件覆盖率是多少?
if (a>1 and b=0) then
x=x/a
if (a=2 or x>1) then
   x=x+1
else
   a=b+1
else
x=x-1


case1: a=1 b=0 x=3

scorix 发表于 2007-7-22 19:10:15

可能我们分析出的结果和用工具分析出的结果不同
但是逻辑覆盖测试是一种白盒的动态测试,是要运行程序的

碎片 发表于 2007-7-23 23:01:03

希望对于上面的问题,大家是不屑回答,而不是不会回答

seifer1754 发表于 2007-7-24 11:00:08

对楼主的回复

原帖由 碎片 于 2007-7-22 13:30 发表 http://bbs.51testing.com/images/common/back.gif
问题:
1.什么是覆盖率?
2.覆盖率到底是干什么的?
3.覆盖率检测是在什么时候进行的?
4.覆盖率检测到底要不要执行程序?



if (a>1 and b=0)
x=x/a;
if (a=2 or x>1)
x=x+1;

针对上面的程序段, ...

在测试中的代码覆盖率是指你运行测试用例后,走过了多少句代码,拿这个走到过的代码除以你这个测试对象的代码行数,就是你这次测试的代码覆盖率了。
比如说,你测试的对象是一个函数,这个函数有100行代码,你所有的测试用例执行完后,走过了60行的代码,还有40行的代码没有走到过,那你这个函数的代码就只被覆盖了60%。
我们编写代码时,一定会反复调试保证它能够编译通过。所以我们会对代码的每一个分支条件和分支结果都要进行测试,覆盖率就是我们对这些测试的一个度量。
覆盖率是在我们的用例执行后进行统计的,是要运行程序的。

对于文中的例子,采用这两个 case, 我们可以设计如下的驱动,来对函数进行测试:

#include<stdio.h>

int fun(int a, int b)
{
    int x = 0;
   
    if (a > 1 && b == 0)
      x=x/a;
    if (a == 2 || x > 1)
      x=x+1;

    return x;
}


int x = 0, y = 0, z = 0;

int main(int argc, char *argv[])
{
    int caseno;
    for(caseno = 0; caseno <= 2; i ++)
   {
      switch(caseno)
   {
       case 1:

       x = 1;
       y = 0;
       z = 0;

       break;

       case 2:

       x = 2;
       y = 1;
       z = 1;
      
       break;

       default :
       break;

      }

       z = fun(x,y);

       printf("The result is %d",z);

   }

    return 0;
}

对于代码的测试,是与编译器息息相关的,不同的编译器,对代码的编译是有很大的差别的,很可能会影响到代码的输出结果。
我是在PowerPC 平台上对这个代码进行调试的,解析出来的汇编代码如下:(为了方便,我在这里只将被测函数的汇编码摘要出来)

   int fun(int a, int b)
{
1.   0x40fc   fun:               7c6a1b78   mr      r10 <a>, r3
2.   0x4100fun+0x4:          7c8b2378   mr      r11 <b>, r4
      int x = 0;
3.   0x4104fun+0x8:          39800000   li      r12 <x>, 0
   
       if (a > 1 && b == 0)
4.   0x4108fun+0xc:         2c0a0001   cmpwi   r10 <a>, 1                           
5.   0x410cfun+0x10:         40810010   ble       fun+0x20 (0x411c)               T1 ,F1
6.   0x4110fun+0x14:         2c0b0000   cmpwi   r11 <b>, 0
7.   0x4114fun+0x18:         40820008   bne       fun+0x20 (0x411c)            T2 , F2
      x=x/a;                                                                                             statement 1
8.   0x4118fun+0x1c:         7d8c53d6   divw      r12 <x>, r12 <x>, r10 <a>
      if (a == 2 || x > 1)
9.   0x411cfun+0x20:         2c0a0002   cmpwi   r10 <a>, 2
10. 0x4120fun+0x24:         4182000c   beq       fun+0x30 (0x412c)             T3, F3   
11. 0x4124fun+0x28:         2c0c0001   cmpwi   r12 <x>, 1
12. 0x4128fun+0x2c:         40810008   ble       fun+0x34 (0x4130)               T4,F4
      x=x+1;                                                                                              statement 2
13. 0x412cfun+0x30:         398c0001   addi      r12 <x>, r12 <x>, 1

       return x;
       }
14. 0x4130fun+0x34:         7d836378   mr      r3, r12 <x>
15. 0x4134fun+0x38:         4e800020   blr



从这些汇编来看,我们可以清楚的看出来,对于条件的判断,这个编译器是由左至右来判断的,对于 && 逻辑,当左边的条件不符合,程序会直接跳转,不会再判断右边的逻辑。 对于 || 逻辑,程序会依次判断下来。 我们在跳转语句后面做一些标记,这样看起来更方便一些 ,T代表跳转, F代表不跳转 即逻辑中的真与假。
我们设计用例虽然会考虑全部的条件,可是对于编译器来说,为了提高编译的效率,是不可能对所有的条件都进行判断的。

所以对于case 1, a= 1, b = 0, x = 3; 只能执行 T1,F3,F4 ;statement 1未执行
      对于case 2, a= 2, b = 1, x = 1; 只能执行 F1,T2,T3 ;   statement 1 未执行。

从条件覆盖来看,每个case 都只覆盖了3个跳转语句,从语句覆盖来看,都未覆盖statement 1 .

另外,用工具来统计覆盖率时,一般是将所有的case 都执行完毕才一起统计的,因为单个case 是不可能100%覆盖所有分支的。

因为单元测试,尤其是代码的覆盖率,是跟编译器有非常大的关系的,而覆盖率统计的工具,一般都是对汇编码的覆盖进行统计,所以,要想对覆盖率有详细的了解,最好能够看懂汇编码。

我写的比较简单,如果大家有看不懂的地方,欢迎在下面跟贴提问。

一些拙见,希望能够对大家有所帮助!

[ 本帖最后由 seifer1754 于 2007-7-24 13:25 编辑 ]

seifer1754 发表于 2007-7-25 11:02:22

因为我是用 PowerPC 对这个例子进行编译的,因为CPU架构与Inter的产品不同,所以汇编码和我们常见的 x86 系列汇编有一些不同。
不过我只是想说明在编译器中,代码是要被解析成汇编码的,所进行的分支也是根据汇编指令来控制的。

PS: 2楼说的这句话完全错误

“程序执行了a>1也肯定执行了b=0,他们属于一个语句里的,用括号包起来的
所以都判断了
除非有break强制退出的,才不执行后面的语句。
我是这么认为的”

[ 本帖最后由 seifer1754 于 2007-7-25 11:15 编辑 ]

lhjtc8257 发表于 2007-8-1 13:36:34

原帖由 碎片 于 2007-7-22 13:30 发表 http://bbs.51testing.com/images/common/back.gif
问题:
1.什么是覆盖率?
2.覆盖率到底是干什么的?
3.覆盖率检测是在什么时候进行的?
4.覆盖率检测到底要不要执行程序?



if (a>1 and b=0)
x=x/a;
if (a=2 or x>1)
x=x+1;

针对上面的程序段, ...

1.覆盖率是用来度量测试完整性的一个手段。
2.覆盖率是测试技术有效性的一个度量。
3.覆盖率有单元测试时的逻辑覆盖率;
集成测试时的接口覆盖率;
系统测试时的需求覆盖率;各个阶段都有
以你的这个条件覆盖应属于单元测试的
4.覆盖检测属于动态测试


if (a>1 and b=0)
x=x/a;
if (a=2 or x>1)
x=x+1;属于单元测试覆盖的测试

语句覆盖: a=2,b=0,x=3   100%
判定覆盖: a=2,b=0,x=3   
            a=1,b=0,x=1   100%
条件覆盖: a=2,b=0,x=3
            a=1,b=0,x=1
            a=2,b=1,x=1   100%

判定-条件覆盖:判定覆盖+条件覆盖

路径覆盖: a=2,b=0,x=3
            a=1,b=0,x=1
            a=2,b=1,x=1
            a=3,b=0,x=1   100%
页: [1]
查看完整版本: 关于覆盖率的大疑问---条件覆盖率