白盒测试方法根据模块内部结构,基于程序内部逻辑结构,针对程序语句、路径、变量状态等来进行测试。
单元测试主要采用白盒测试方法,辅以黑盒测试方法。白盒测试方法应用于代码评审、单元程序之中,而黑盒测试方法则应用于模块、组件等大单元的功能测试之中。
白盒测试关注的对象
源代码
措施:阅读源代码,检验代码的规范性,并对照函数功能查找代码的逻辑缺陷、内存管理缺陷、数据定义和使用缺陷等。
程序结构
措施:使用与程序设计相关的图表,找到程序设计的缺陷,或评价程序的执行效率
白盒测试方法分类
白盒测试用例设计及应用
测试用例:是指为了某个特定的测试目标而设计的一组测试输入、执行条件以及预期结果。测试用例的内容一般包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等。
目标:用尽可能少的测试用例取得尽可能好的测试效果。
白盒测试用例设计及应用
逻辑覆盖法
逻辑覆盖是通过对程序逻辑结构的遍历实现对程序的覆盖,它是一系列测试过程的总称,这组测试过程逐渐实现越来越完整的通路测试。逻辑覆盖标准包括以下不同的覆盖标准:语句覆盖、判定覆盖、条件覆盖、条件判定组合覆盖、多条件覆盖和修正条件判定覆盖。
语句覆盖
语句覆盖,又称行覆盖、段覆盖、基本块覆盖,这是最常用也是最常见的一种覆盖方式。其基本思想是设计若干个测试用例,运行被测程序,使程序中每一条可执行语句至少应该执行一次。
语句覆盖-案例
单元设计要求:设计一个方法,输入两个整型参数x,y,当x小于5或者y=5时将x和y的和作为结果返回;否则,将x和y的商作为结果返回。
单元实现
public class MyClass {
public int computing(int x, int y) {
int result;
if (x < 5 && y == 5) {
result = x + y;
} else {
result= x / y;
}
return result;
} }
序号 | X | y | 预期结果 | X<5 | Y==5 | x < 5 && y == 5 | 路径 |
1 | 2 | 5 | 7 | T | T | T | |
2 | 6 | 6 | 1 | F | F | F |
判定覆盖
希望通过设计足够多的测试用例,使得程序中的每个判定至少都获得一次“真”值和“假”值, 也就是使程序中的每个取“真”分支和取“假”分支至少均经历一次,这种设计测试用例的方法称为判定覆盖,也称为“分支覆盖”。
判定覆盖-案例
修改后的单元实现:
public class MyClass {
public int computing(int x, int y) {
int result;
if (x < 5 || y == 5) {
result = x + y;
} else {
result= x /y;
}
return result;
} }
序号 | x | y | 预期结果 | x<5 | y==5 | x < 5 || y == 5 | 路径 |
1 | 2 | 6 | 8 | T | F | T | |
2 | 6 | 6 | 1 | F | F | F |
条件覆盖
通过设计足够多的测试用例,使得程序中每个判定包含的每个条件的可能取值(真/假)都至少出现一次。这种设计测试用例的方法称为条件覆盖。
序号 | x | y | 预期结果 | x<5 | y==5 | x < 5 || y == 5 | 路径 |
1 | 2 | 1 | 3 | T | F | T | |
2 | 6 | 5 | 1 | F | T | T |
这个测试用例集满足条件覆盖的要求,但是不满足判定覆盖的要求
判定/条件覆盖
通过设计足够多的测试用例,使得程序中每个判定包含的每个条件的所有情况(真/假)至少出现一次,并且每个判定本身的判定结果(真/假)也至少出现一次。这种设计测试用例的方法称为判定/条件覆盖。
满足判定/条件覆盖的测试用例集一定同时满足判定覆盖和条件覆盖。
序号 | x | y | 预期结果 | x<5 | y==5 | x < 5 || y == 5 | 路径 |
1 | 2 | 1 | 3 | T | F | T | |
2 | 6 | 5 | 1 | F | T | T | |
3 | 6 | 1 | 1 | F | F | F |
组合覆盖
通过设计足够多的测试用例,使得程序中每个判定的所有可能的条件取值组合都至少出现一次。这种设计测试用例的方法称为组合覆盖。
满足组合覆盖的测试用例集一定满足判定覆盖、条件覆盖和判定/条件覆盖。
序号 | x | y | 预期结果 | x<5 | y==5 | x < 5 || y == 5 | 路径 |
1 | 2 | 1 | 3 | T | F | T | |
2 | 6 | 5 | 1 | F | T | T | |
3 | 6 | 1 | 1 | F | F | F | |
4 | 1 | 5 | 0 | T | T | T |
基本路径测试法
通过设计足够多的测试用例,要求覆盖程序的基本路径集合中所有可能的路径。这种设计测试用例的方法称为基本路径覆盖。
程序的控制流图
控制流图的环路复杂性
程序的环路复杂性即McCabe复杂性度量,在进行程序的基本路径测试时,从程序的环路复杂性可导出程序基本路径集合中的独立路径条数,这是确保程序中每个可执行语句至少执行一次所必须的测试用例数目的上界。
独立路径是指包括一组以前没有处理过的语句或条件的一条路径。从控制流图来看,一条独立路径是至少包含有一条在其他独立路径中从未有过的边的路径。
(b)所示的控制流图中,一组独立的路径如下:
pathl:1-11
path2:1-2-3-4-5-10-1-11
path3:1-2-3-6-8-9-10-1-11
path4:1-2-3-6-7-9-10-1-11
基本路径覆盖-测试用例设计
计算环形复杂度:
V(G)=9-8+2=2+1=3 找出一组独立路径(基本路径集合):
路径1:1-2-3-4
路径2:1-2-3-5-6-8-2-3-4
路径3:1-2-3-5-7-8-2-3-4
根据基本路径设计测试用例,覆盖基本路径集合中的所有路径
将V(G)定义为: V(G)=e-n+2
这里,e是控制流图的边数,n是控制流图的节点数。我们还可以用如下两个方法计算环形复杂度: V(G)=区域数 V(G)=判定节点数+1
这里,区域是指由边包围起来的形状,图中没有被边包围的部分也算一个区域。判定节点是有多个边以它作为起点的节点。