白盒测试理解
白盒测试
白盒技术:白盒测试是结构测试,所以被测对象基本上是源程序,以程序的内部逻辑为基础设计测试用例。因此白盒测试需要测试人员对源程序的内部结构了解。
白盒测试用例设计方法包括:逻辑覆盖法和路径法
其中逻辑覆盖包括:语句覆盖,判定覆盖,条件覆盖,判定条件覆盖,条件组合覆盖
路径法包括:路径覆盖
逻辑覆盖法
下面使用判断闰年的程序做说明:
#include <iostream>
using namespace std;
int main()
{
int input;
cin >> input;
if (input < 0) {
cout << "请输入大于0年份!";
}
else {
if ((input % 4 == 0 && input % 100 != 0) || (input % 400 == 0)) {
cout << input << " 年是闰年" << endl;
}
else {
cout << input << " 年不是闰年" << endl;
}
}
return 0;
}
序号 | 测试用例 |
---|---|
1 | -1 |
2 | 2008 |
3 | 1900 |
1、语句覆盖:设计若干个测试用例,运行测试程序,每个可执行语句都必须至少执行一次
首先int input; cin >> input;
这两句代码每个用例都覆盖到,不做多说。
用例1覆盖了
if (input < 0) {
cout << "请输入大于0年份!";
}
用例2覆盖了(cout << "请输入大于0年份!";
不执行)
if (input < 0) {
}
else {
if ((input % 4 == 0 && input % 100 != 0) || (input % 400 == 0)) {
cout << input << " 年是闰年" << endl;
}
用例3覆盖了(cout << input << " 年是闰年" << endl;
不执行)
if (input < 0) {
}
else {
if ((input % 4 == 0 && input % 100 != 0) || (input % 400 == 0)) {
}
else {
cout << input << " 年不是闰年" << endl;
}
}
因此所有用例结合起来使得程序的每一条语句都至少被执行一次,这些用例为语句覆盖用例。
2、判定覆盖:设计若干个测试用例,然后运行被测程序,使得程序中的每个判断的取真分支和取假分支至少经历一次。
还是使用上面的测试用例说明:
用例1对if (input < 0)
取真分支;
用例2对if (input < 0)
取假分支,并对if ((input % 4 == 0 && input % 100 != 0) || (input % 400 == 0))
取真分支;
用例3对if (input < 0)
取假分支,并对if ((input % 4 == 0 && input % 100 != 0) || (input % 400 == 0))
取假分支。
综合看来,3个测试用例可以覆盖这两个“ if ”判断分支,所以为判定覆盖用例。
3、条件覆盖:设计若干个测试用例,然后运行被测程序,要使每个判断中每个条件的可能取值至少满足一次。
还是用上面的测试用例说明:
用例1对if (input < 0)
条件中的input<0
取True值一次;
用例2对if (input < 0)
条件中的input<0
取False值一次,并对if ((input % 4 == 0 && input % 100 != 0) || (input % 400 == 0))
中的input % 4 == 0
取True值一次,input % 100 != 0
取True值一次和(input % 400 == 0)
取False值一次。
用例3对if (input < 0)
条件中的input<0
取False值一次,并对if ((input % 4 == 0 && input % 100 != 0) || (input % 400 == 0))
中的input % 4 == 0
取True值一次,input % 100 != 0
取False值一次和(input % 400 == 0)
取False值一次。
综上,由于input % 4 == 0
取False值和(input % 400 == 0)
取True值没有覆盖,所以这些测试用例并不符合条件覆盖,因此我们需要添加额外两个测试用例:
序号(接上表) | 测试用例 |
---|---|
4 | 5 |
5 | 2000 |
添加这两测试用例后,用例4覆盖input % 4 == 0
取False值,用例5覆盖(input % 400 == 0)
取True值,最后用例1,2,3,4,5组成条件覆盖,所以条件覆盖的要求比判定覆盖的要求更高。
4、判定条件覆盖:设计若干个测试用例,然后运行被测程序,使得判断中每个条件的所有可能至少出现一次,并且每个判断本身的判定结果至少出现一次
其实这个覆盖是前面判定覆盖和条件覆盖的结合。前面的判定覆盖我们可以覆盖每个判断语句的判定结果,而分析条件覆盖的时候是在判定覆盖的基础上,再添加了2个测试用例,也符合条件覆盖用例,所以我们可以把用例1,2,3,4,5作为判定条件用例。
5、条件组合覆盖:设计若干测试用例,运行被测程序,使得每个判断的所有可能的条件取值组合至少执行一次。
显然满足条件组合覆盖的设计用例一定符合判定覆盖、条件覆盖和判定条件覆盖。由于我们这里的条件input % 4 == 0 && input % 100 != 0
符合input % 100 == 0
而input % 4 != 0
的用例是不存在的,所以这个条件组合是永远不能被执行的。在这个测试里我个人觉得不存在条件组合覆盖的测试用例。
到此,语句覆盖,判定覆盖,条件覆盖,判定条件覆盖和条件组合覆盖分析完毕。
路径法
首先我们需要构建一个程序流图,程序流图构建符合一下约定:
a.条件判定构成流图的一个节点,每个判定分支结束时增加一个汇聚节点,多个汇聚节点可合并
b.顺序结构可以使用一个节点表示
c.区域包括封闭区域和开放区域
那么接上面的闰年判断程序,画流图:
先画程序流程图:
程序控制流图:
有了控制流图,我们可以找出所有的路径,下面使用路径表达式概括路径:
A(B(D+E)+C)F
拆分:
ABDF+ABEF+ACF,所以一共3个路径
1、路径覆盖:设计若干测试用例,覆盖程序中所有可能的路径
在设计路径覆盖的时候我们除了需要流图,还需要计算流图的环复杂度:V(G) = P+1,其中P是判断节点的个数。得到环复杂度是为了确定基本路径数目,因为环复杂度 = 基本路径数目
最后我们确定基本路径集合:即只包含独立路径的集合
独立路径:从入口到出口,至少有一条与其他路径不同的边的路径
用上面的控制流图看:V(G) = 2+1 = 3,基本路径数为3,独立路径集合为:{ABDF,ABEF,ACF}
回到上表的用例:
用例1覆盖了路径ACF;
用例2覆盖了路径ABEF;
用例3覆盖了路径ABDF.
所以用例1,2,3可以组成该程序的路径覆盖测试集
总结
语句覆盖是最弱的逻辑覆盖,效果有限,最好与其他方法交互使用,条件组合覆盖是比较强的逻辑覆盖,但是有可能会遗漏路径,路径覆盖是最强的覆盖准则,但是当路径数目很大的时候,做到完全覆盖是非常困难的,因此需要把覆盖路径压缩到一定程度。
上一篇: bluecms灰盒测试
下一篇: JAVA基础-变量