图是由节点和边构成的集合;其中,节点是有穷非空集合;
节点:
假设图只有一个初始节点和一个终止节点;
若实际图中有多个初始节点,则通过添加一个呀节点,使其指向所有的初始节点,并把呀节点重新规定为初始节点,从而把图归结为一个初始节点;
若实际图中有多个终止节点,也可通过添加呀节点方法使图只有一个终止节点;
测试路径是从初始节点到终止节点的路径;表达测试的执行;
注意:
相同的测试路径可能会被不同的测试执行,即不同的测试输入,其测试路径是一样的;
有些测试路径是不会被任何测试执行;
一条测试只能执行一条测试路径;
path(t)表示测试t执行的测试路径;path(T)表示测试用例集T中所有测试用例执行的测试路径集合;
可达:
语法可达:在语法构建的图结构中存在一条路径可到达子图;
语义可达:在实际程序中存在一条测试可到达子图;
覆盖:
某个节点在一条测试路径内,称该测试路径覆盖该节点;
某条边在一条测试路径内,称该测试路径覆盖该边;
某条子路径在一条测试路径内,称该测试路径覆盖该子路径;
结构覆盖:
仅关注图的点和边,不关心里面内容(源代码、需求文档、设计图);
测试需求与测试准则:
测试需求:描述测试路径性质的定义;
测试准则:描述测试需求的规则;
顶点覆盖VC:
边覆盖EC:
满足边覆盖,则一定满足顶点覆盖;反之不然;
边对覆盖EPC:(相邻的两条bain)
完全覆盖CPC:
n路径覆盖nPC:VC(n=0), EC(n=1), EPC(n=2), CPC(n=无穷大)
把软件变成图的方法:控制流图
控制流图CFG:程序执行的流转过程;其中,顶点可以是语句、语句块、函数、模块等,边可以是顶点之间的流转、跳转等;
举例:代码的控制结构转换成控制流图
1 if语句
2 if-return语句
出现多个终止节点,通过添加一个呀节点,所有终止节点指向该呀节点,并将其作为终止节点,则构成一个起始节点、一个终止节点;
3 while语句
4 do-while语句
这是一个被压缩的控制流图;
也可在2节点后添加一个新节点,去控制while循环条件,更加清晰;
5 for语句
6 break和continue语句
7 switch语句
8 计算平均值与方差的函数
节点1表示初始化变量;节点2表示初始化变量i;节点3表示for循环的控制条件;节点4表示满足循环条件执行的循环体;
节点5表示不满足循环条件执行赋值语句,其实是两个节点的合并;节点6表示for循环的控制条件;节点7表示表组循环条件执行的循环体;
节点8表示不满足循环条件执行后续语句;
注意:实际应用中,我们不可能人工生成图结构;但可利用现有工具Soot产生控制流图;
数据流关注顶点上的操作是否正确;
数据流操作分为定义def(把变量值放入内存中,如赋值、初始化等)、使用use(如分支、判断、循环等);
def(n) & def(e):节点n和边e的定义变量;
use(n) &use(e):节点n和边e的使用变量;
定义引用对(DU Pair):控制对(li,lj)的两个地方构成DU对是指在前面li上定义,在后面lj上使用;
定义清晰(Def-clear):li定义到lj使用的中间关于变量v没有重新定义过;
可达(Reach):数据流的可达是指一条定义清晰的路径可以从li到lij;
定义引用路径(DU-Path):定义清晰且简单的子路径;
定义引用路径覆盖准则:ADC(定义覆盖)、AUC(引用覆盖)、ADUPC(定义引用路径覆盖);
举例:
Junit是Java单元测试框架;