目录
一、白盒测试的概念理解
二、白盒测试的分类
1、静态分析
2、动态分析
(1)逻辑覆盖测试
a、语句覆盖
b、判定覆盖
c、条件覆盖
d、判定条件覆盖
e、条件组合覆盖
f、路径覆盖
(2)基本路径测试法
3、总结
一、白盒测试的概念理解
我们以往说的测试通常是基于黑盒测试,即不需要了解具体的程序代码而进行的测试。白盒测试是在程序代码的层面进行的测试,所以和黑盒测试的方法是截然不同的。
白盒测试又称为结构测试、逻辑驱动测试,白盒测试需要遵循的四大原则:
① 保证一个模块中的所有路径至少被测试一次;
② 所有逻辑值都要测试真(true)和假(false)的两种情况;
③ 检查程序的内部数据都要真实有效;
④ 检查上、下边界以及可操作范围内运行所有循环。
二、白盒测试的分类
白盒测试主要分为静态分析和动态分析。
1、静态分析
静态分析是指不运行代码程序,通过桌面检查、代码审查、代码走查、代码扫描工具等方式对代码和文档进行检查。
在该阶段常见的代码错误有:
① 参数传递错误,少传递/传递错参数;
② 数组索引越界;
③ 空指针异常、未初始化直接使用;
④ 边界错误,例如int c = a / b,是否考虑 b = 0 的情况;
⑤ 经验错误,例如if(a == 3)的判定条件写成了 if(a = 3);
⑥ 算法逻辑错误,例如玩家角色受到伤害后,血量自动减1,但是实际上血量并没有减。
......
2、动态分析
动态分是指运行代码程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能。
动态分析的测试流程:
① 选取定义域内的有效值,或定义域外的无效值(等价类思想);
② 对已选取的值进行预期;
③ 用已选取值执行程序;
④ 执行结果与预期结果进行对比,不吻合则有错误。
(1)逻辑覆盖测试
逻辑覆盖测试指的是通过对程序逻辑结构的遍历来实现程序的覆盖。当程序运行起来时,需要走到每一个item上。item指语句、判定、条件、判定条件、条件组合、路径。
以上6中覆盖方式发现错误的能力由弱到强变化:
① 语句覆盖 每条语句至少执行一次;
② 判定覆盖 每个判定的分支至少执行一次;
③ 条件覆盖 每个判定的每个条件应渠道各种可能的值;
④ 判定条件覆盖 同时满足判定覆盖和条件覆盖;
⑤ 条件组合覆盖 每个判定中各条的每一种组合至少出现一次;
⑥ 路径覆盖 时程序中每一条可能的路径至少执行一次。
在这个过程中,代码覆盖率要尽可能的高。
代码覆盖率:
覆盖率 = 至少被执行一次的 item 数 / item总数
例如:代码中一共有4条可执行的语句,设计测试用例执行了3条,则语句覆盖率为3/4 = 0.75
a、语句覆盖
看每一行的代码是否被覆盖到。
例如:
static int logicExample(int x,int y,int magic){
int a;
if(x>0&&y>0){
//语句块1
a=x+y+10;
}else {
//语句块2
a=x+y-10;
}
if(magic<0){
//语句块3
a=0;
}
//语句块4
return a;
}
程序流程图:
要想实现语句覆盖率达到100%,就要测试到所有的语句块,则需要执行的测试用例:
① {x = 1, y = 1, maigc = 2} ,覆盖了语句1 + 语句4,语句覆盖率:50%(2/4)
② {x = -1, y = -1, maigc = -2} ,覆盖了语句2 + 语句3 + 语句4,语句覆盖率:75%(3/4)
但是语句覆盖的方法仍然存在局限性,对于if判定的条件,无法每一个都覆盖到,比如在上述的if条件中,范围是 x>0 && y>0,但是用例中只涉及了x=1&&y=1一种情况,无法令每个判定都被组合一遍。
使用以上测用例时,
正确代码:if(x>0 && y >0)
错误代码:if(x>0 || y>0) 无法被发现
可见语句覆盖不能准确的判断运算中的逻辑关系错误。
在六种逻辑覆盖标准中,语句覆盖是最弱的。
b、判定覆盖
要求每个判定的真(true)和假(false)都至少执行一次。
判定覆盖率 = 每个判定的真假值至少出现一次 / 判定结果的总数。
例如:针对上一个代码,做判定覆盖的时候,使得程序代码中的每一个判定至少获得一次真和一次假。
设计测试用例如下:
① {x = 1, y = 1, maigc = 2} :x>0 && y>0为true,magic<0为false;判定覆盖率:50%(2/4)
② {x = -1, y = -1, maigc = -2} :x>0&&y>0为false,magic<0为true;判定覆盖率:50%(2/4)
但是判定覆盖会忽略条件中取或(or) 的情况。
使用以上测用例时,
正确代码:if(x>0 && y >0)
错误代码:if(x>0 || y>0) 无法被发现
只要满足了判定覆盖,就一定满足语句覆盖。
c、条件覆盖
要求判定中的每个条件至少有一次取真值,有一次取假值。并且当遇到多个if条件覆盖的情况时,需要使用到条件覆盖。
条件覆盖率 = 每个条件真假值至少出现一次 / 条件结果的总数。
针对上一个代码中,有2个判定,3个条件。条件结果为6个:
判定1:if(x>0 && y >0)
x>0 为真 T1,x>0 为假 -T1;
y>0 为真 T2,y>0 为假 -T2;
判定2:if(magic<0)
magic<0 为真 T3,magic<0 为假 -T3;
则要想每个条件至少有一次真一次假,可以设计测试用例如下:
T1,-T2,T3
-T1,T2,-T3
已经满足每个条件至少有一次真一次假了。可以设计测试用例为:
① {x = 3, y = 0, maigc = -2} 条件覆盖率:50%(3/6)
② {x = -3, y = 1, maigc = 2} 条件覆盖率:50%(3/6)
但是针对该用例,判定1为真的情况并没有涉及。因此条件覆盖并不能保证判定覆盖。
d、判定条件覆盖
要求判定中的每个条件至少有一次取真值,有一次取假值,并且每个判定至少有一次取真值,有一次取假值。
判定条件覆盖率 = 每个判定真假值和条件真假值至少出现一次 / (判定结果的总数 + 条件结果的总数)
即同时满足100%判定覆盖和100%条件覆盖。
针对上一个代码中,有2个判定,3个条件。条件结果为6个,判定结果为4个:
判定1:if(x>0 && y >0)
x>0 为真 T1,x>0 为假 -T1;
y>0 为真 T2,y>0 为假 -T2;
判定2:if(magic<0)
magic<0 为真 T3,magic<0 为假 -T3;
判定1为真 P1,判定1为假 -P1;
判定2为真 P2,判定2为假 -P2;
则要想满足每个判定和每个条件的真假值至少出现一次,可以设计测试用例如下:
T1,T2,T3 =>P1,P2
-T1,-T2,-T3 =>-P1,-P2
已经满足每个判定和每个条件的真假值至少出现一次了。可以设计测试用例为:
① {x = 3, y = 3, maigc = -2} 判定条件覆盖率:50%((3+2)/(6+4))
② {x = -3, y = 0, maigc = 2} 判定条件覆盖率:50%((3+2)/(6+4))
满足判定条件覆盖,一定满足条件覆盖、判定覆盖和语句覆盖。
但是判定条件覆盖会忽略条件取或(or)的情况。
使用以上测用例时,
正确代码:if(x>0 && y >0)
错误代码:if(x>0 || y>0) 无法被发现
e、条件组合覆盖
要求每个判定中条件结果的所有可能组合至少执行一次。
针对上一个代码中,有2个判定,3个条件。判定1有2个条件,判定2有1个条件。则判定1的条件组合为4个,判定2的条件组合为2个。
判定1:if(x>0 && y >0)
x>0 为真 T1,x>0 为假 -T1;
y>0 为真 T2,y>0 为假 -T2;
判定2:if(magic<0)
magic<0 为真 T3,magic<0 为假 -T3;
判定1为真 P1,判定1为假 -P1;
判定2为真 P2,判定2为假 -P2;
判定1的条件组合:
T1,T2
-T1,-T2
-T1,T2
T1,-T2
判定2的条件组合:
T3
-T3
设计的测试用例:
T1、T2、T3
-T1、-T2、-T3
T1,-T2,T3
-T1,T2,-T3
条件组合覆盖满足语句覆盖、判定覆盖、条件覆盖、判定条件覆盖。但条件组合覆盖不能保证所有的路径被执行。
f、路径覆盖
覆盖被测试程序中的所有可能路径,是最强的覆盖准则。
设计测试用例:
a-b-d-f => T1,T2,T3
a-b-e-f => T1,T2,-T3
a-c-d-f => -T1,T2,T3
a-c-e-f => -T1,T2,-T3
T2为假的情况并未涉及。
路径覆盖可以对程序进行彻底的测试,比前面5种覆盖面都要广。但是满足路径覆盖,并不一定能满足条件覆盖,也就不能满足条件组合覆盖。
(2)基本路径测试法
路径覆盖要覆盖程序中所有可能的路径,但是但路径数目很庞大时,无法真正做到覆盖所有的路径。
基本路径测试法就是在程序控制流图的基础上,通过分析控制流图的环形复杂度,导出基本可执行的集合。保证被测程序的每一条可执行语句至少执行一次。
程序控制流图: