路径分析与测试
1.基础路径:
基本路径是指所有程序路径作为一个集合,在这些路径当中必然存在一个最小路径的集合。基本路径测试通过确定测试用例是否完全覆盖基本路径而进行测试。
基本路径测试法是在程序控制流图的基础上,通过分析控制构造环路复杂性,导出基本可执行路径集合,设计测试用例。
2.基本路径的测试方法:
基本路径测试法主要步骤如下所示。
步骤一:以详细设计或源代码作为基础,导出程序的控制流图。
步骤二:计算控制流图G的圈复杂度V(G)。 圈复杂度为程序逻辑复杂性提供定量的测度,该度量用于计算程序的基本独立路径数目,确保所有语句至少执行一次的测试数量的上界。
步骤三:确定独立路径的集合,即确定线性无关的路径的基本集。独立路径是指至少引入程序的一个新处理语句集合或一个新条件的路径,即独立路径必须包含一条在定义之前不曾使用的边。
步骤四:测试用例生成,确保基本路径集中每条路径的执行。
图5.6 控制流图G
3.计算圈复杂度的方法:
方法一:控制流图G的圈复杂度V(G)的定义为V(G)=E-N+2,E是图中边的数量,N是图中结点的数量。
方法二:将圈复杂度定义为控制流图中的区域数。
方法三:V(G)=P+1,P是控制流图G中判定(谓词)结点的数量。
方法四:将控制流图转化为连接矩阵,根据图5.5原理,可得图5.6中的判定结点为4,故圈复杂度同样为5。
4.独立路径表示
独立路径:所谓独立路径,是指至少包含一条新边的路径,也就是包含一些前面的路径未包含的语句。
路径1 : 1-11
路径2 : 1-2-3-4-5-10-1-11
路径3 : 1-2-3-6-8-9-10-1-11
路径4 : 1-2-3-6-7-9-10-1-11
5.Z路径覆盖
为解决实际操作中路径覆盖难以实现问题,必须舍弃一些次要因素,简化循环结构,从而极大地减少路径的数量,使得覆盖这些有限的路径成为可能。采用简化循环方法的路径覆盖就是Z路径覆盖。
所谓简化循环就是减少循环的次数,不考虑循环体的形式和复杂度如何,也不考虑循环体实际上需要执行多少次,
只考虑通过循环体零次和一次这两种情况。零次循环是指跳过循环体,从循环体的入口直接到循环体的出口。通过一次循环体是指检查循环初始值。根据简化循环的思路,循环要么执行,要么跳过,这和判定分支的效果是一样的可见,简化循环就是将循还结构编程选择结构。
6.独立路径测试及测试用例生成
独立路径测试法主要步骤如下所示。
第一步:以详细设计或源代码作为基础,导出程序的控制流图。
程序控制流图
控制流图
第二步:计算环路复杂度V(G)
圈复杂度为程序逻辑复杂性提供定量的测度,该度量用于计算程序的基本独立路径数目,确保所有语句至少执行一次的测试数量的上界。
计算如下:
流图中有四个区城;
V(G)=10条边-8结点+2=4;
V(G)=3个判定结点+1=4.
第三步:导出测试用例,确定独立路径的集合,即确定线性无关的路径的基本集。
根据上面的计算方法,可得出四个独立的路径。(一条独立路径是指,和其他的独立路径相比,至少引入一个新处理语句或一个新判断的程序通路。V(G)值 正好等于该程序的独立路径的条数。)
独立路径是指至少引入程序的一个新处理语句集合或一个新条件的路径,即独立路径必须包含一条在定义之前不曾使用的边。
路径1: 4-14
路径2: 4-6-7-14
路径3: 4-6-8-10-13-4-14
路径4: 4-6-8-11-13-4-14
根据上面的独立路径,去设计输入数据使程序分别执行到上面四条路径
第四步:准备测试用例,确保基本路径集中每条路径的执行。
为了确保基本路径集中的每一条路径的执行,根据判断结点给出的条件,选择适当的数据以保证某一条路径可以被测试到,满足上面例子基本路径集的测试用例是:
void Sort(int iRecordNum,int iType){
int x=0;
int y=0;
while(iRecordNum-- >0)
{
if( 0 == iType){
x=y+2;
break;
}else{
if(1 == iType)
x=y+10;
else
x=y+20;
}
}
路径1:4-14
输入数据:iRecordNum=0,或者取iRecordNum<0的某个取值
预期结果:x=0,y=0;
路径2: 4-6-7-14
输入数据: iRecordNum= 1, iType= 0
预期结果: x=2
路径3: 4-6-8-10-13-4-14
输入数据: iRecordNum= I, iType= 1
预期结果: x= 10
路径4: 4-6-8-11-13-4-14
输入数据: iRecordNum= 1, iType = 2
预期结果: x= 20
7.独立独立路径测试及测试用例生成步骤总结:
流程图一控制流图
计算圈复杂度
找到四条基本路径
根据基本路径找到输入输出
数据流测试分析
控制流一逻辑
数据流一定义和使用
定义使用异常缺陷
变量被定义,但从来没有使用(引用)
所使用的变量没有被定义
变量在使用之前被定义两次
数据流测试指关注变量接收值(点)和使用(或引用)这些值(点)的路径,是结构性测试方法的一种。
1.定义节点def:
会发现,当且仅当变量v的值是用对应节点,用对应的语句片段所定义时,节点N是变量V的定义节点,执行时与变量相关的存储单元内内容会改变,其实这就是我们所说的赋值。
输入语句,赋值语句,循环控制语句和过程调用。
2.使用节点use:
输出语句,赋值语句,条件语句,循环控制语句和过程调用。
3.谓词使用P-use/计算使用C-use
当且仅当语句原因是谓词语句时,使用节点use是一个谓词使用,否侧use就是一个所谓的计算使用。
谓词使用对应谓词使用的节点的出度>=2
计算使用对应计算使用的节点的出度<=1
3.使用路径use-path
使用路径是指PATH中使得对某个节点属于V的节点中,存在和定义使用节点DEF和USE之间使得M和N是该路径的所谓最终节点或者最初节点。(
定义节点可出现多次)
4.清除路径dc-path
是具有最初和最终节点,DEF和USE节点、PATH路径使得路径中其他的节点都是定义节点(
定义节点出现 一次)
使用路径和清除路径描述了从值被定义的点到值被使用的点的源数据的数据流。
例如:
变量的定义和使用
1 a=5; //定义a
2 While(C1) {
3 if (C2){
4 b=a*a;//使用a
5 a=a-1;//定义且使用a
6 }
7 print(a); } //使用a
Du-path dc-path
1234 y
1237 y
12345 y
1234567 n
567 y
5.测试用例的产生的步骤:
●选择定义/使用路径测试覆盖指标
●由测试覆盖指标构造定义/使用路径
●选择一条路径,使得其至少包含一条“定义/使用路径”
●由路径产生测试用例
6.定义-使用路径测试覆盖指标
数据流指标假设所有程序变量都标识了定义节点和使用节 点,且关于各变量都标识了定义-使用路径
T:拥有变量集合V的程序P的程序图G(P)中的一个路径集合
7.全定义准则
集合T满足程序b的全定义准则,当且仅当所有变量v∈V,T包含从v的每个定义节点到v的一个使用的定义清除路径。
8.全使用准则
集合T满足程序P的全使用准则,当且仅当所有变量v∈V,T包含从v的每个定义节点到v的所有使用以及到所有USE(v,n)后续节点的定义清除路径。
9.全谓词使用/部分计算使用准则
集合T满足一样的规则,如果这些谓词使用没有一个谓词使用的时候,我们就认为需要有一个计算使用作为定义点
10.全计算使用/部分谓词使用准则
假设如果没有计算使用,那么我们会发现所有的定义清除节点就会导致一个谓词使用。
11.全定义-使用路径准则
它包含从v到V的一个所有使用以及到所有USE VIN的后续节点所有路径
定义/使用测试提供一种检查缺陷可能发生点的严格和系统化的方法。
变异测试
尽可能缩小错误押索的范围
1.变异测试(Mutation Testing):
(有时也叫做“变异分析”)是一种在细节方面改进程序源代码的软件测试方法。这些所谓的变异,是基于良好定义的变异操作,这些操作或者是模拟典型应用错误(例如:使用错误的操作符或者变量名字),或者是强制产生有效地测试(例如使得每个表达式都等于0)。目的是帮助测试者发现有效地测试,或者定位测试数据的弱点,或者是在执行中很少(或从不)使用的代码的弱点。
2.分类
(1)程序强变异测试(程序变异)
(2)程序弱变异测试
3.基本思想
P e1,e2 ,···, en
P' P1,P2 ,···, Pn
P i称为P的变异因子测试数据Ci
C={C1,C2,····,Cn}
如果对每一个Ci,P都是正确的,而Pi都是错误的,这说明P的正确性较高。
如果对某个Ci, P是错误的,而Pi是正确的,这说明P存在错误,而错误就是ei。
4.缺点
-
需要大量的计算机资源来完成测试充分性分析
-
对于一个中等规模的软件,所需的存储空间巨大
-
运行大量变异因子导致时间上巨大的开销
-
实际使用中,对故障类型难以把握
-
变异测试局限性很大
5.强变异
给定一个程序P和一个测试数据集T,通过变异算子为P产生一组变异体Mi ( 合乎语法的变更),对P和M都使用T进行测试运行,如果某Mi在某个测试输入t.上与P产生不同的结果,则该Mi 被杀死;若某Mi在所有的测试数据集上都与P产生相同的结果,则称其为活的变异体。接下来对活的变异体进行分析,检查其是否等价于P;对不等价于P的变异体M进行进一步的测试, 直到充分性度量达到满意的程度。
假设程序P已使用测试T中的测试用例测试通过,而且没有错误。变异是一种轻微改变程序的操作。
C(n)=C(n)+1
n=1,2,3,·····,n;
练习
一、选择题
1. 以下不属于白盒测试技术的是( D )。
A. 逻辑覆盖 B. 基本路径测试 C. 循环覆盖测试 D. 等价类划分
2. 以下不属于逻辑覆盖的是( D )。
A. 语句覆盖 B. 判定覆盖 C. 条件覆盖 D. 基本路径
3. ( A )方法根据输出对输入的依赖关系设计测试用例。
A. 路径测试 B. 等价类 C. 因果图 D. 归纳测试
4. McCabe建议模块规模应满足V(G)≤( A )。
A. 20 B. 10 C. 30 D. 40
5.下列关于覆盖逻辑,说法错误的是( B )
A.满足条件覆 盖并不一-定 满足判断覆盖
B.满足条件组合覆盖的测试一定满足判断覆盖、条件覆盖和判定/条件覆盖
C.满足路径覆盖也- -定满足条件组合覆盖
D.满足判断1条件覆盖同时满足判定覆盖和条件覆盖
6.使用白盒测试方法时,确定测试数据应根据( A )和指定的覆盖标准
A.程序的内部逻辑
B. 程序的复杂程度
C.使用说明书
D.程序的功能
7.白盒测试方法的优点是( C )
A.可测试软件的特定功能
B. 能站在用户立场上测试
C.可按软件内部结构测试
D.可发现实现功能需求中的错误
二、简答题
1. 白盒测试是什么?白盒测试和黑盒测试的区别体现在哪些方面?
答:
白盒测试也称结构测试或逻辑驱动测试,它是按照程序内部的结构 测试程序,通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进 行,检验程序中的每条通路是否都能按预定要求正确工作。 这一方法是把测试 对象看作一个打开的盒子, 测试人员依据程序内部逻辑结构相关信息, 设计或选 择测试用例, 对程序所有逻辑路径进行测试, 通过在不同点检查程序的状态, 确 定实际的状态是否与预期的状态一致。
黑盒测试也称功能测试或数据驱动测试, 它是在已知产品所应具有的 功能, 通过测试来检测每个功能是否都能正常使用,在测试时,把程序看作一个不能打开的黑盒子, 在完全不考虑程序内部结构和内部特性的情况下, 测试者在 程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使 用,程序是否能适当地接收输入数锯而产生正确的输出信息, 并且保持外部信息 (如数据库或文件)的完整性。黑盒测试方法主要有等价类划分、边值分析、因 —果图、错误推测等,主要用于软件确认测试。 “黑盒”法着眼于程序外部结 构、不考虑内部逻辑结构、针对软件界面和软件功能进行测试。 “黑盒”法是穷 举输入测试, 只有把所有可能的输入都作为测试情况使用, 才能以这种方法查出 程序中所有的错误。 实际上测试情况有无穷多个, 人们不仅要测试所有合法的输 入,而且还要对那些不合法但是可能的输入进行测试。
白盒测试也称结构测试或逻辑驱动测试, 它是知道产品内部工作过程, 可通过测试来检测产品内部动作是否按照规格说明书的规定正常进行, 按照程序 内部的结构测试程序,检验程序中的每条通路是否都有能按预定要求正确工作, 而不顾它的功能, 白盒测试的主要方法有逻辑驱动、 基路测试等, 主要用于软件 验证。
白盒测试技术 (White Box Testing) : 深入到代码一级的测试, 使用这种技术 发现问题最早,效果也是最好的。 该技术主要的特征是测试对象进入了代码内部, 根据开发人员对代码和对程序的熟悉程度,对有需要的部分进行在软件编码阶 段,开发人员根据自己对代码的理解和接触所进行的软件测试叫做白盒测试。 这 一阶段测试以软件开发人员为主,在 JAVA 平台使用 Xunit 系列工具进行测 试, Xunit 测试工具是类一级的测试工具对每一个类和该类的方法进行测试
2. 为什么说语句覆盖是最弱的逻辑覆盖?
答:
语句覆盖对一些控制结构不敏感,不能发现判断中逻辑运算符的错 误,覆盖率低。
3. 条件覆盖为什么不一定包含判定覆盖?
答:
条件覆盖比判定覆盖增加了对符合条件情况的测试,增加了测试路 径,但条件覆盖只能保证每个条件至少有一次为真,为不考虑所有的判定结果。
4.采用白盒法进行测试时,测试用例覆盖路径的种类有哪几种? 它们相互之间是什么关系?
答:
覆盖路径:
1、 语句覆盖
2 、 判定覆盖
3 、 条件覆盖
4 、 判定、条件覆盖
5 、 条件组合覆盖
他们之间的关系:
1. 语句覆盖是很不充分的一种标准。
2. 判断覆盖比语句覆盖更严格, 因为如果每个根治执行过了, 则每个 语句也就执行过了。
3. 条件覆盖比判断覆盖强因为他使一个判定中的每一个条件都去到两个不同的结果,而判定覆盖则不保证这一点。
4. 满足条件组合覆盖的测试用例、 是一定满足判定覆盖, 条件覆盖和 判定、条件覆盖的。
5. 请把下面的程序流程图转换成控制流图。
答: