标签:
2016-08-23
1 白盒测试的概念
2 白盒测试的主要目的
3 测试覆盖标准
4 白盒测试的主要方法
4.1 逻辑驱动测试
4.1.1 语句覆盖
4.1.2 判定覆盖(分支覆盖)
4.1.3 条件覆盖
4.1.4 判定/条件覆盖
4.1.5 条件组合覆盖
4.1.6 黑盒法补充测试用例
4.2 路径测试
4.2.1 基本路径测试
1) 控制流图
2) 独立路径
3) 基本路径测试
4) 工具方法:图形矩阵
5 控制结构测试的其他变种
5.1 条件测试
5.1.1 条件
5.1.2 条件测试的目的
5.1.3 条件测试策略
5.2 循环测试
6 面向对象的白盒测试
6.1 类测试方式
6.1.1 结构性测试
7 白盒测试工具
8 总结
白盒测试也称结构测试或逻辑驱动测试,是一种测试用例设计方法,它从程序的控制结构导出测试用例。(测试用例由测试输入数据以及与之对应的输出结果组成。)
白盒测试使用被测单元内部如何工作的信息,允许测试人员对程序内部逻辑结构及有关信息来设计和选择测试用例,对程序的逻辑路径进行测试。基于一个应用代码的内部逻辑知识,测试是基于覆盖全部代码、分支、路径、条件。
白盒法特点:以程序的内部逻辑为基础设计测试用例,所以又称为逻辑覆盖法。应用白盒法时,手头必须有程序的规格说明以及程序清单。
白盒法考虑的是测试用例对程序内部逻辑的覆盖程度。最彻底的白盒法是覆盖程序中的每一条路径,但是由于程序中一般含有循环,所以路径的数目极大,要执行每一条路径是不可能的,只能希望覆盖的程度尽可能高些。
图1 程序流程图
图1包括了一个执行达20次的循环。那么它所包含的不同执行路径数高达520(=1013)条,若要对它进行穷举测试,覆盖所有的路径。假使测试程序对每一条路径进行测试需要1毫秒,同
样假定一天工作24小时,一年工作365天, 那么要想把如图所示的小程序的所有路径测试完,则需要3170年。
为了衡量测试的覆盖程度,需要建立一些标准,目前常用的一些覆盖标准从低到高分别是:
基本路径测试
程序1如下:
PROCEDURE M(VAR A,B,X:REAL); BEGIN IF (A>1) AND (B=0) THEN X:=X/A ; IF (A=2) OR (X>1) THEN X:=X+1 ; END
图2 程序流程图
为使程序中每个语句至少执行一次,只需设计一个能通过路径ace的例子就可以了,就可达到“语句覆盖”标准。例如选择输入数据为:
A=2,B=0,X=3
缺点: 从上例可看出,语句覆盖实际上是很弱的
对程序1,如果设计两个用例,使它们能通过路径ace和abd,或者通过路径acd和abe,就可达到“判定覆盖”标准,为此,可以选择输入数据为:
优点:“分支覆盖”比“语句覆盖”严格,因为如果每个分支都执行过了,则每个语句也就执行过了。
缺点:但是,“分支覆盖”还是很不够的
一个判定中往往包含了若干个条件,如程序中,判定 (A>1) AND (B=0)包含了两个条件: A>1以及 B=0,所以可引进一个更强的覆盖标准——“条件覆盖”。
程序1有四个条件:
A>1 、B=0、A=2、X>1
为了达到“条件覆盖”标准,需要执行足够的测试用例使得在a点有:
A>1、A≤1、B=0、B≠0
以及在b点有:
A=2、A≠2、X>1、X≤1
现在只需设计以下两个测试用例就可满足这一标准:
优点:“条件覆盖”通常比“分支覆盖”强,因为它使一个判定中的每一个条件都取到了两个不同的结果,而判定覆盖则不保证这一点。
缺点:“条件覆盖”并不包含“分支覆盖”,如两个用例没有有覆盖判定(A>1 and B=0)为True的情况
程序1,以下用例是满足判定/条件覆盖:
优点:既有“条件覆盖”,又有“判定覆盖”
缺点:分支/条件覆盖从表面来看,它测试了所有条件的取值,但是实际上某些条件掩盖了另一些条件。
因此,采用分支/条件覆盖,逻辑表达式中的错误不一定能够查出来了。
程序1,以下用例是满足条件组合覆盖:
再看程序1,我们需要选择适当的用例,使得下面 8种条件组合都能够出现:
1) A>1, B=0 2) A>1, B≠0 3) A≤1, B=0 4) A≤1, B≠0
5) A=2, X>1 6) A=2, X≤1 7) A≠2, X>1 8) A≠2, X≤1
5) 、6) 、7)、8)四种情况是第二个 IF语句的条件组合,而X的值在该语句之前是要经过计算的,所以还必须根据程序的逻辑推算出在程序的入口点X的输入值应是什么。
下面设计的四个用例可以使上述 8种条件组合至少出现一次:
优点:既有“条件覆盖”,又有“判定覆盖”,还有“条件组合覆盖”
缺点:上面四个例子虽然满足条件组合覆盖,但并不能覆盖程序中的每一条路径,例如路径acd就没有执行
通过前面逻辑驱动测试方法,可以得到两点结论:
一个参考的黑盒法补充策略是:
1) 在任何情况下都需使用边界值分析(这个方法应包括对输入和输出的边界值进行分析)。
2) 必要的话,再用等价分类法补充一些测试用例。
3) 再用错误推测法附加测试用例。
4) 检查上述例子的逻辑覆盖程度,如果未能满足某些覆盖标准,则再增加足够的测试用例。
5) 如果功能说明中含有输入条件的组合情况,则一开始就可先用因果图(判定表)法。
路径测试就是设计足够多的测试用例,覆盖被测试对象中的所有可能路径。
程序1是很简单的程序函数,只有四条路径。但在实践中,一个不太复杂的程序,其路径都是一个庞大的数字,要在测试中覆盖所有的路径是不现实的。为了解决这一难题,只得把覆盖的路径数压缩到一定限度内,例如,程序中的循环体只执行一次。
基本路径测试就是这样一种测试方法,它在程序控制图的基础上,通过分析控制构造的环行复杂性,导出基本可执行路径集合,从而设计测试用例的方法。设计出的测试用例要保证在测试中程序的每一个可执行语句至少执行一次。
在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例。包括以下4个步骤和一个工具方法:
工具方法:
在介绍基本路径方法之前,必须先介绍一种简单的控制流表示方法,即流图。流图是对待测试程序过程处理的一种表示。流图使用下面的符号描述逻辑控制流,每一种结构化构成元素有一个相应的流图符号。
图3 流图符号
流图只有二种图形符号
任何过程设计都要被翻译成控制流图。
在将程序流程图简化成控制流图时,应注意:
图4 控制流图
如果判断中的条件表达式是由一个或多个逻辑运算符 (OR, AND) 连接的复合条件表达式,则需要改为一系列只有单条件的嵌套的判断。
图5 程序结构转化成流图
独立路径:至少沿一条新的边移动的路径
图6 独立路径
对以上路径的遍历,就是至少一次地执行了程序中的所有语句
第一步:画出控制流图
流程图用来描述程序控制结构。可将流程图映射到一个相应的流图(假设流程图的菱形决定框中不包含复合条件)。
图7 程序流程图
图8 程序流程图和对应的控制流图
第二步:计算圈复杂度
圈复杂度是一种为程序逻辑复杂性提供定量测度的软件度量,将该度量用于计算程序的基本的独立路径数目,为确保所有语句至少执行一次的测试数量的上界。
独立路径必须包含一条在定义之前不曾用到的边。
有以下三种方法计算圈复杂度:
第三步:导出测试用例
根据上面的计算方法,可得出四个独立的路径。(一条独立路径是指,和其他的独立路径相比,至少引入一个新处理语句或一个新判断的程序通路。V(G)值正好等于该程序的独立路径的条数。)
第四步:准备测试用例
为了确保基本路径集中的每一条路径的执行,根据判断结点给出的条件,选择适当的数据以保证某一条路径可以被测试到,满足上面例子基本路径集的测试用例是:
路径1:4-14
输入数据:iRecordNum=0,或者取iRecordNum<0的某一个值 预期结果:x=0
路径2:4-6-7-14
输入数据:iRecordNum=1,iType=0 预期结果:x=2
路径3:4-6-8-10-13-4-14
输入数据:iRecordNum=1,iType=1 预期结果:x=10
路径4:4-6-8-11-13-4-14
输入数据:iRecordNum=1,iType=2 预期结果:x=20
必须注意,一些独立的路径,往往不是完全孤立的,有时它是程序正常的控制流的一部分,这时,这些路径的测试可以是另一条路径测试的一部分。
导出控制流图和决定基本测试路径的过程均需要机械化,为了开发辅助基本路径测试的软件工具,称为图形矩阵(graph matrix)的数据结构很有用。
利用图形矩阵可以实现自动地确定一个基本路径集。一个图形矩阵是一个方阵
对每个矩阵项加入连接权值(link weight),图矩阵就可以用于在测试中评估程序的控制结构,连接权值为控制流提供了另外的信息。最简单情况下,连接权值是 1(存在连接)或0(不存在连接),但是,连接权值可以赋予更有趣的属性:
图9 图形矩阵
连接权为“1”表示存在一个连接,在图中如果一行有两个或更多的元素“1”,则这行所代表的结点一定是一个判定结点,通过连接矩阵中有两个以上(包括两个)元素为“1”的个数,就可以得到确定该图圈复杂度的另一种算法。
前面所述的基本路径测试技术是控制结构测试技术之一。尽管基本路径测试简单高效,但是,其本身并不充分。下面讨论控制结构测试的其他变种,这些测试覆盖并提高了白盒测试的质量。包括:
条件测试方法注重于测试程序中的条件。是检查程序模块中所包含逻辑条件的测试用例设计方法。
程序中的条件分为简单条件和复合条件。
简单条件是一个布尔变量或一个可能带有NOT(“!”)操作符的关系表达式。关系表达式的形式如:
E1<关系操作符>E2
其中E1和E2是算术表达式,而<关系操作符>是下列之一:“<”、“≤”、“=”、“≠”(“!=”)、“>”、或“≥”。
复合条件由简单条件通过逻辑运算符(AND、OR、NOT)和括号连接而成,不含关系表达式的条件称为布尔表达式。
所以条件的成分类型包括:布尔操作符、布尔变量、布尔括弧(括住简单或复杂条件)、关系操作符、算术表达式。
条件测试是测试程序条件错误和程序的其他错误。如果程序的测试集能够有效地检测程序中的条件错误,则该测试集可能也会有效地检测程序中的其他错误。此外,如果测试策略对检测条件错误有效,则它也可能有效地检测程序错误。
有n个变量的布尔表达式需要2n个可能的测试(n>0)。这种策略可以发现布尔操作符、变量和括弧的错误,但是只有在n很小时实用。
分支测试可能是最简单的条件测试策略,它是真假分支必须至少执行一次的路径策略,对于复合条件C,C的真分支和假分支以及C中的每个简单条件都需要至少执行一次。
域测试是对于大于、小于和等于值的测试路径策略。域测试要求从有理表达式中导出三个或四个测试,有理表达式的形式如:
E1<关系操作符>E2
需要三个测试分别用于计算E1的值是大于、等于或小于E2的值。如果<关系操作符>错误,而E1和E2正确,则这三个测试能够发现关系算子的错误。为了发现E1和E2的错误,计算E1小于或大于E2的测试应使两个值间的差别尽可能小。
如果在一个判定的复合条件表达式中每个布尔变量和关系运算符最多只出现一次,而且没有公共变量,应用一种称之为BRO(分支与关系运算符)的测试法可以发现多个布尔运算符或关系运算符错,以及其他错误。
BRO策略引入条件约束的概念。设有n个简单条件的复合条件C,其条件约束为D= (D1,D2,…,Dn) ,其中Di(0<i≤n)是条件C中第i个简单条件的输出约束。如果在C的执行过程中,其每个简单条件的输出都满足D中对应的约束,则称条件C的条件约束D由C的执行所覆盖。对于布尔变量或布尔表达式B,B的输出约束必须是真(t)或假(f);对于关系表达式,其输出约束为符号>、=、< 。
循环测试是一种白盒测试技术,注重于循环构造的有效性。
有四种循环:简单循环,串接(连锁)循环,嵌套循环、不规则循环。
图10 循环结构
对于简单循环,测试应包括以下几种,其中的n表示循环允许的最大次数。
对于嵌套循环,不能将简单循环的测试方法简单地扩大到嵌套循环,因为可能的测试数目将随嵌套层次的增加呈几何倍数增长。这可能导致一个天文数字的测试数目。下面是一种有助于减少测试数目的测试方法。
从最内层循环开始,设置所有其他层的循环为最小值;
对于串接循环,要区别两种情况。
对于非结构循环,不能测试,应重新设计循环结构,使之成为其它循环方式,然后再进行测试。
对OO软件的类测试相当于传统软件的单元测试。和传统软件的单元测试不同,他往往关注模块的算法细节和模块接口间流动的数据,OO软件的类测试是由封装在类中的操作和类的状态行为所驱动的。OO软件测试的特点:
类测试一般有两种主要的方式:
功能性测试和结构性测试,即对应于传统结构化软件的黑盒测试和白盒测试:
结构性测试对类中的方法进行测试,它把类作为一个单元来进行测试。测试分为两层:
每个方法的测试要求能针对其所有的输入情况,但这样还不够,只有对这些方法之间的接口也做同样测试,才能认为测试是完整的。
对于一个类的测试要保证类在其状态的代表集上能够正确工作,构造函数的参数选择以及消息序列的选择都要满足这一准则。因此,在这两个不同的测试层次上应分别做到:
内存资源泄漏检查:Numega中的bouncechecker,Rational的Purify等;
代码覆盖率检查:Numega中的truecoverage,Rational的Purecoverage,Telelogic公司的logiscope,Macabe公司的Macabe等;
开源覆盖率测试软件gCov等。
确保覆盖语句 | 确保覆盖分支 | 确保覆盖条件 | 确保覆盖条件组合 | 确保覆盖基本路径 | ||
逻辑驱动测试 | 语句覆盖 | Y | N | N | N | N |
判定覆盖 | Y | Y | N | N | N | |
条件覆盖 | N | N | Y | N | N | |
判定/条件覆盖 | Y | Y | Y | N | N | |
条件组合覆盖 | Y | Y | Y | Y | N | |
基本路径测试 | 基本路径测试 | Y | Y | N | N | Y |
“白盒”法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。“白盒”法是穷举路径测试。在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。贯穿程序的独立路径数是天文数字。但即使每条路径都测试了仍然可能有错误:
标签:
原文地址:http://www.cnblogs.com/Ming8006/p/5798186.html