实验二 白盒测试 基本路径法
实验目的
(1) 熟练掌握基本路径方法的测试用例设计流程;
(2) 熟练应用基本路径方法进行测试用例设计;
(3) 对测试用例进行优化设计。
实验内容
题目1:输入3个0-10000内的整数,求3个数中的最大数。根据程序流程图,绘制流图,计算圈复杂度,按照从简单到复杂的原则,导出基本路径集,设计测试用例,运行测试用例,分析测试结果,并对发现的错误进行原因分析。
步骤1:绘制程序流图
如该程序流程图,可知该程序有三个判断,分别是
判断1:a,b,c三个数是否均大于等于0且小于等于10000
判断2:数字a是否大于数字b
判断3:数字c是否大于取值后的max值
可绘制流图如下:
A: a>=0且 a<=10000
B: b>=0且 b<=10000
C: c>=0且 c<=10000
D: 数据无效
E: a>b
F: max=a
G: max=b
H: c>max
I: max=c
J: cout<<max
K: 程序出口
步骤二:计算圈复杂度
由图可知圈复杂度V(G)=15-11+2=6
步骤三:导出基本路径集
P1: A-D-K
P2: A-B-C-D-K
P3: A-B-C-E-G-H-J-K
P4: A-B-C-E-F-H-J-K
P5: A-B-C-E-F-H-I-J-K
P6: A-B-C-E-G-H-I-J-K
步骤四:设计并运行测试用例
序号 | 测试用例 | 条件 | 判定 | 实际输出 | 测试结果 |
1 | 输入:a=-1 b=2 c=3 预期输出:数据无效 | 条件A错误 | 判定L错误 | 数据无效 | √ |
2 | 输入:a=1 b=2 c=-3 预期输出:数据无效 | 条件A、B正确,条件C错误 | 判定L错误 | 数据无效 | √ |
3 | 输入:a=4 b=5 c=3 预期输出:5 | 条件A、B、C正确,条件E、H错误 | 判定L正确,M、N错误 | 3 | × |
4 | 输入:a=4 b=3 c=2 预期输出:4 | 条件A、B、C、E正确,条件H错误 | 判定L、M正确,N错误 | 2 | × |
5 | 输入:a=4 b=3 c=5 预期输出:5 | 条件A、B、C、E、H正确 | 判定L、M、N正确 | 4 | × |
6 | 输入:a=3 b=4 c=5 预期输出:5 | 条件A、B、C、H正确,条件E错误 | 判定L、N正确,M错误 | 4 | × |
表1. 基于条件组合覆盖的测试用例集
如下为该程序的程序代码:
#include <iostream.h>
void main(void)
{
int a,b,c,max;
cout<<"请输入 3 个整数:"<<endl;
cin>>a>>b>>c;
max=0;
if(a>=0 && a<=10000 && b>=0 && b<10000 && c>=0 && c<=10000)
{
if(a>b)
max=a;
else
max=b;
if(c<max)
max=c;
cout<<"max=: "<<max<<endl;
}
else
{
cout<<"输入的整数超出 0~10000,不满足条件!"<<endl;
}
思考:采用程序流程图和流图的区别在哪里?圈复杂度计算的依据是什么?
程序流程图和流图的区别:
程序流程图是描述系统数据流程的工具,它将数据独立抽象出来,通过图形方式描述信息的来龙去脉和实际流程。而程序流图描述的是逻辑控制流,每个圆表示一个或多个非分支PDL或源代码语句。箭头称为边或连接,表示控制流。
流图的实质是弱化的程序流程图。流图中的一个节点可以表示程序流程图中的一个顺序处理序列和一个菱形判定框。流图是程序控制结构的图形表示,其基本要素是过程块、结点、判定。与程序流程图不同的是,流图中不显示过程块的细节,而在程序流程图着重于过程属性的描述。
圈复杂度的计算依据:
圈复杂度所反映的是“判定条件”的数量,所以圈复杂度实际上就是等于判定节点的数量再加上1,也即控制流图的区域数,对应的计算公式为:V(G)= P + 1。
(2) 题目2:根据程序流程图,绘制流图,根据基本路径法的流程一次导出
基本路径集,设计测试用例,运行测试用例,分析测试结果,并对发现的错误进行原因分析。
步骤1:绘制程序流图
如该程序流程图,可知该程序有两个判断,分别是
判断1:a是否大于0且b是否大于10
判断2:a是否小于0或b是否小于0
可绘制流图如下:
A: 程序入口
B: a>0
C: b>10
D: b=b-a
E: a<0
F: b=-(a+b)
G: b<0
H: cout<<a且cout<<b
步骤二:计算圈复杂度
由图可知圈复杂度V(G)=11-8+2=5
步骤三:导出基本路径集
P1: A-B-E-F-H
P2: A-B-E-G-F-H
P3: A-B-C-E-F-H
P4: A-B-C-E-G-F-H
P5: A-B-C-D-E-F-H
步骤四:设计并运行测试用例
序号 | 测试用例 | 条件 | 判定 | 实际输出 | 测试结果 |
1 | 输入:a=0 b=2 预期输出:0 2 | 条件B,E错误 | 判定M,N错误 | 0 -2 | × |
2 | 输入:a=0 b=-2 预期输出:0 2 | 条件B错误,条件E正确 | 判定M错误,判定N正确 | 0 -2 | × |
3 | 输入:a=4 b=5 预期输出:4 5 | 条件B正确,条件C,E错误 | 判定M,N错误 | 4、-9 | × |
4 | 输入:a=4 b=-3 预期输出:4 -1 | 条件B,E正确,条件C错误 | 判定M错误,判定N正确 | 4、-3 | × |
5 | 输入:a=4 b=11 预期输出:4 7 | 条件B,C正确,条件E错误 | 判定M正确,判定N错误 | 4、-11 | × |
如下为该程序的程序代码:
#include <iostream>
using namespace std;
void main(void)
{
int a, b;
cout << "请输入 2 个整数:" << endl;
cin >> a >> b;
if (a > 0 && b > 10)
b = b - a;
if (a < 0 || b>0)
b = -(a + b); cout << "a: " << a << endl;
cout << "b: " << b << endl;
}
思考:程序流程图和程序流图什么时候是完全一致的?什么时候结构有明显
区别?
答:当程序的判断为原子判断时,可以得知程序流程图和程序流图完全一致,当程序的判断中含有多个条件,会导致两者结构有明显区别。
实验分析
根据实验一的结果可知,当判定L错误时程序在两个测试用例的检测下都是正确的,而当判定L正确时,另外四个测试结果始终与预期结果不相符合,可以得知该实验代码主要在max的取值时发生了错误。
根据实验二的结果可知,五个实验结果均与预期输出不相符合,可知该程序在对逻辑判断上出现了错误,也可能是在两个判断之间的包含关系上出现错误,导致输出不理想。
实验总结
总结:本次实验通过用基本路径法测试覆盖,完成了示例程序的白盒测试。
虽然基本路径法实现较为简单,但是在使用的时候,还是注意逻辑问题,程序流图错误可能会导致后续步骤全部出现错误。在画流图时,我发现使用判断节点加一和边数减节点数加二两相比较,结果相同可以保证流图的正确性。