白盒测试又称为结构测试或逻辑驱动测试,是针对被测试程序单元内部如何工作的测试,特点是基于被测试程序的源代码,而不是软件的需求规格说明。
白盒测试充分利用被测单元内部的控制信息,允许测试人员对程序内部逻辑结构及有关信息来设计和选择测试用例,对程序的逻辑路径进行测试。 其考虑的是测试用例对程序内部逻辑的覆盖程度,基本目标是覆盖程序中的每一条路径。 但是由于程序中一般含有循环,所以路径的数目极大。
(动态)白盒测试方法:基本路径测试法 主路径测试法 基于逻辑覆盖的测试法 针对循环的测试 基于数据流的测试 变异测试 ... ...
控制流图(Control flow graph,简称CFG)也叫控制流程图,它用图的方式来描述程序的控制流程,是对一个过程或程序的抽象表达。 在控制流图中,用节点来代表操作、条件判断及汇合点,用弧或者叫控制流线来表示执行的先后顺序关系。
控制流图是一种有向图,可以形式化为: G = (N, E, N_entry, N_exit) N是节点集,程序中的每个语句都对应图中的一个节点,有时一组顺序执行、不存在分支的语句也可以合并为用一个节点表示。 边集 E = {< n1,n2 > | n1, n2∈ N,且 n1 执行后,可能立即执行n2 }。 N_entry 和 N_exit 分别为程序的入口和出口节点,具有唯一的入口结点 N_entry 和唯一的出口结点 N_exit。
可以根据程序来得出其控制流图,也可以由程序流程图来转换得到控制流图。
控制流图可以通过简化程序流程图得到,简化后的流图只有两种图形符号:结点和控制流线。 结点用带标号的圆圈表示,可以代表一个或多个语句、一个处理框或一个判断框。 控制流线用带箭头的弧线表示,代表程序中控制流。
根据源代码构建控制流图时需注意: 控制流图仅仅关注逻辑走向,而不关注中间的每一条语句的具体含义。 在顺序结构中,尽管可能包含了多条语句(语句块),但是在控制流图仅仅用一个节点表示。
简单的用程序的大小来度量程序的复杂度是片面和不准确的。 程序中的控制路径越复杂,环路越多,则环路复杂度越高,环路复杂度用来定量度量程序的逻辑复杂度。 环路复杂度(又称为圈复杂度),是一种为程序逻辑复杂度提供定量尺度的软件度量。
在把程序抽象为有向图之后,我们把从程序入口到出口经过的各个节点的有序排列称为路径,可用路径表达式来表示这样的一条路径。 路径表达式可以是节点序列,也可以是弧(有向边)序列。
完全的路径覆盖一般不可能
既然无法对一个实际的应用程序进行路径的穷举测试,那么就只能选取部分路径来进行测试。 折中采用基本路径覆盖来替代全路径覆盖。一条路径是基本路径,那么其应满足: 1)是一条从入口节点到出口节点的路径; 2)该路径至少包含一条其它基本路径没有包含的边。
一个控制流图中,基本路径的最大数量可以用环路复杂度来表示。 圈复杂度给出了独立路径数的上限。
基本路径测试的基本步骤为: (1)根据程序设计结果导出程序流程图的控制流图; (2)计算程序的圈复杂度; (3)根据控制流图,构造程序的基本路径集合,其上限为圈复杂度。 (4)根据(3)中的基本路径,设计测试用例的输入数据和预期输出。
例一:
(1)绘制出程序代码对应的控制流图,如下图所示。
(2)计算环路复杂度V(G)。
V(G)=E-N+2=14-12+2=4;
V(G)=判定点数+1=3+1=4
V(G)=区域数=4
(3)确定独立路径集合。
1-2-3-11-12
1-2-4-5-10-11-12
1-2-4-6-7-9-10-11-12
1-2-4-6-8-9-10-11-12
(4)根据基本路径设计测试用例
测试用例编号 |
测试数据 |
预期执行结果 |
测试路径 |
1 |
year=1001 |
leap=0 |
1-2-3-11-12 |
2 |
year=1004 |
leap=1 |
1-2-4-5-10-11-12 |
3 |
year=1100 |
leap=0 |
1-2-4-6-7-9-10-11-12 |
4 |
year=2000 |
leap=1 |
1-2-4-6-8-9-10-11-12 |
例2:
第二步,计算程序环路复杂度。 方法1:二值判定数量加1,所以环路复杂度为5。 方法2:利用公式:V(G)=e-n+2计算,其中e为图G中的边数,n为图G中的结中数 。 V(G)=12-9+2=5。 方法3:按区域数计算环形复杂数,有4个小区域,加上图形外一个区域,共有5个,因此环形复杂度为5。
第三步,确定独立路径集。 因为环形复杂数为5,所以最多有5条基本路径 : path1:1—2—4—5—6—7 path2:1—2—3—4—5—6—7 path3:1—2—3—8—4—5—6—7 path4:1—2—3—8—4—5—9—7 path5:1—2—3—8—4—5—6—9—7
第四步,设计测试用例。 path1:1—2—4—5—6—7
ID |
输入数据 |
通过的路径 |
||
x |
y |
z |
||
TE1-014 |
1 |
0 |
1 |
Path1 |
TE1-015 |
3 |
1 |
1 |
Path2 |
TE1-016 |
3 |
0 |
3 |
Path3 |
TE1-017 |
2 |
0 |
2 |
Path4 |
TE1-018 |
3 |
0 |
6 |
Path5 |
路径:一个节点或者边的序列
路径长度:边的数目 单一节点可看作是长度为0的路径
子路径:路径p的子序列称为p的子路径
环:起点和终点相同的路径
测试路径:控制流图中一条开始于起始节点、结束于终止节点的路径 测试路径代表测试用例的执行
主路径覆盖 : 设计测试路径使得图中每条主路径都被覆盖到
如何求出覆盖所有主路径的测试路径集?
列举覆盖所有节点的路径集P 例如:广度搜索每个起始节点到其它节点的路径 将路径集P扩展为测试路径集TP 对不含终止节点的路径p,将其拓展到终止节点 根据TP生成覆盖所有主路径的测试路径集 对不被TP覆盖的主路径,根据TP拓展为测试路径 去除冗余测试路径