1、第第 四四 章章白盒测试基本概念白盒测试基本概念1逻辑覆盖逻辑覆盖2基本路径测试基本路径测试3循环测试循环测试4面向对象的白盒测试面向对象的白盒测试5其他白盒测试方法简介其他白盒测试方法简介6主主要要内内容容第四章第四章 白盒测试方法白盒测试方法白盒测试的基本概念白盒测试的基本概念白盒测试:把程序看成装在白盒测试:把程序看成装在一个透明的盒子里,程序的一个透明的盒子里,程序的结构和处理过程完全可见,结构和处理过程完全可见,按照程序的内部逻辑测试程按照程序的内部逻辑测试程序,以检查程序中的每条通序,以检查程序中的每条通路是否都能按照预先要求正路是否都能按照预先要求正确工作。确工作。白盒测试针对被
2、测单元的内白盒测试针对被测单元的内部进行,它的突出特点是基部进行,它的突出特点是基于被测程序的于被测程序的源代码源代码,而不,而不是基于软件的规格说明书。是基于软件的规格说明书。白盒测试方法的分类白盒测试方法的分类静态测试静态测试:着重在于纠正软件系统在描述、表示和规:着重在于纠正软件系统在描述、表示和规格上的错误,是进一步测试的格上的错误,是进一步测试的前提,方法包括:前提,方法包括: 桌面检查(桌面检查(Desk checking) 代码评审(代码评审(Code reading/review) 走查走查(Walkthroughs)动态测试动态测试:根据程序的控制结构设计:根据程序的控制结构
3、设计测试用例,要求:测试用例,要求: 保证一个模块中的所有独立路径至少执行一次保证一个模块中的所有独立路径至少执行一次 对所有逻辑值均需测试对所有逻辑值均需测试True和和False 在上下边界及可操作范围内运行所有循环在上下边界及可操作范围内运行所有循环 检查内部数据结构以确保其有效性检查内部数据结构以确保其有效性白盒测试的常用方法白盒测试的常用方法逻辑覆盖逻辑覆盖基本路基本路径测试径测试 程序结程序结构分析构分析 插桩插桩WHILE 循环结构 顺序结构 UNTIL循环结构 IF选择结构 CASE 多分支结构选择结构 控制流图的图形符号控制流图的图形符号 R3 R2 R1 区域 (a)程序流
4、程图 ) 7 1 2 3 4 5 6 8 1(b)控制流图 1 2 6 4 7 8 9 10 11 边 结点 R4 白盒测试基本概念白盒测试基本概念1逻辑覆盖逻辑覆盖2基本路径测试基本路径测试3循环测试循环测试4面向对象的白盒测试面向对象的白盒测试5其他白盒测试方法简介其他白盒测试方法简介6主主要要内内容容第四章第四章 白盒测试方法白盒测试方法逻辑覆盖以程序的内部逻辑结构逻辑覆盖以程序的内部逻辑结构为基础,主要分以下几种方式:为基础,主要分以下几种方式:逻逻 辑辑 覆覆 盖盖语句覆盖语句覆盖判定覆盖判定覆盖条件覆盖条件覆盖判定条件覆盖判定条件覆盖条件组合覆盖条件组合覆盖路径覆盖路径覆盖1 语语
5、 句句 覆覆 盖盖Statement Coverage设计足够多的测试用例,设计足够多的测试用例,使得程序中的每个语句至使得程序中的每个语句至少执行一次。少执行一次。1 语语 句句 覆覆 盖盖入口入口A 1AND B=0TA=2OR X 1TX = X / AX = X + 1返回返回FF用例用例ABX1204语句覆盖对程语句覆盖对程序的逻辑覆盖很序的逻辑覆盖很少,只能测试部少,只能测试部分语句,是很弱分语句,是很弱的逻辑判断标准。的逻辑判断标准。语语 句句 覆覆 盖盖测试用例测试用例:a = 10, b = 5int foo(int a, int b)return a / b; 尽管语句覆盖
6、率达到了所谓的尽管语句覆盖率达到了所谓的100%,但是却没有发现最简单的但是却没有发现最简单的Bug,如:,如:b=0时会出现一个除零异常。时会出现一个除零异常。2 判判 定定 覆覆 盖盖Dicision Coverage 不仅每个语句都必须至少不仅每个语句都必须至少执行一次,而且每个判定表达式执行一次,而且每个判定表达式的每种可能的结果都应该至少执的每种可能的结果都应该至少执行一次,即每个判定的行一次,即每个判定的“真真”分分支支和和“假假”分支至少都执行一分支至少都执行一次次。判定。判定覆盖又称分支覆盖。覆盖又称分支覆盖。2 判定覆盖判定覆盖(分支覆盖分支覆盖)用例用例ABX12042 1
7、 1 1判定覆盖比语判定覆盖比语句覆盖强,但是句覆盖强,但是对程序逻辑的覆对程序逻辑的覆盖程度仍然不高。盖程度仍然不高。入口入口A 1AND B=0TA=2OR X 1TX = X / AX = X + 1返回返回FF123 条条 件件 覆覆 盖盖Condition Coverage 不仅每个语句都必须至少执不仅每个语句都必须至少执行一次,而且每个判定表达式中行一次,而且每个判定表达式中的每个条件都取到各种可能的结的每个条件都取到各种可能的结果,即每个条件的果,即每个条件的“真真”条件条件和和“假假”条件条件至少至少都执行一都执行一次。次。3 条条 件件 覆覆 盖盖用例用例ABX12042 1
8、 1 1A1, B!=0, A=2, X=1A1条件覆盖条件覆盖1:用例用例ABX12112 1 0 3入口入口A 1AND B=0TA=2OR X 1TX = X / AX = X + 1返回返回FF12程序中共有程序中共有4个条件个条件8个结果个结果A1, B=0,A=2, X1 (全真全真)A=1, B!=0, A!=2, X=1(全假全假)条件覆盖条件覆盖2:请思考:这个条请思考:这个条件覆盖的测试用件覆盖的测试用例是否完全?例是否完全?真假真假混搭混搭 条件覆盖通常比判定覆盖强,因为它使判条件覆盖通常比判定覆盖强,因为它使判定表达式中每个条件都取到了两个不同的结果,定表达式中每个条件
9、都取到了两个不同的结果,而判定覆盖只关心整个判断表达式的值。在上而判定覆盖只关心整个判断表达式的值。在上页的测试用例中,页的测试用例中,条件覆盖条件覆盖1不但覆盖了所有判不但覆盖了所有判定表达式中各条件的所有可能结果,而且覆盖定表达式中各条件的所有可能结果,而且覆盖了所有判定的真、假分支,覆盖性很强。但并了所有判定的真、假分支,覆盖性很强。但并不是所有满足条件覆盖的要求的测试数据都能不是所有满足条件覆盖的要求的测试数据都能满足判定覆盖的要求,如满足判定覆盖的要求,如条件覆盖条件覆盖2.条件覆盖特点条件覆盖特点判定覆盖判定覆盖 vs 条件覆盖条件覆盖判定覆盖:判定覆盖: (1)a = 5, b
10、= 5 覆盖了覆盖了分支分支一一 (2)a = 15, b = 15 覆盖了覆盖了分支二分支二int foo(int a, int b)if (a 10 | b 1AND B=0TA=2OR X 1TX = X / AX = X + 1返回返回FF125 条条 件件 组组 合合 覆覆 盖盖Condition Combination Coverage 设计设计足够多的测试用例,足够多的测试用例,使得每个使得每个判定表达式中条件判定表达式中条件的各种可能组合都至少出现的各种可能组合都至少出现一次。一次。5 条件组合覆盖条件组合覆盖a点的所有条件组合:点的所有条件组合:(1)A1, B0 ; (2)
11、A1, B0(3)A 1, B0 ; (4)A 1, B0b点的所有条件组合:点的所有条件组合:(5)A2, x1 ; (6)A2, x1(7)A 2, x1 ; (8)A 2, x1入口入口A 1AND B=0TA=2OR X 1TX = X / AX = X + 1返回返回FFab一组测试用例一组测试用例:满足满足(1)和和(5): A2, B0, x4满足满足(2)和和(6): A2, B1, x1满足满足(3)和和(7): A1, B0, x2满足满足(4)和和(8): A1, B1, x1第二组测试用例第二组测试用例:满足满足(1)和和(8): A3, B0, x1满足满足(2)和和
12、(7): A3, B1, x2满足满足(3)和和(6): A无取值无取值, B0, x1满足满足(4)和和(5): A无取值无取值, B1, x2满足条件组合覆盖标准的满足条件组合覆盖标准的测试数据,也一定满足判定测试数据,也一定满足判定覆盖、条件覆盖和判定覆盖、条件覆盖和判定/条件条件覆盖标准,是这几种覆盖标覆盖标准,是这几种覆盖标准中最强的。不过它不一定准中最强的。不过它不一定使程序中每条路径都执行到。使程序中每条路径都执行到。条件覆盖条件覆盖 vs 条件组合覆盖条件组合覆盖条件覆盖条件覆盖 (3个条件个条件6个结果个结果): (1) a = 5, b = 7, c = 6(全真)(全真)
13、(2) a = 7, b = 9, c = 4(全假)(全假)int foo(int a, int b)if (a 6 | b 5) ) /判定判定h return 1; 条件组合覆盖条件组合覆盖:k条件条件h条件条件: (1) c 5; (2) c = 5测试用例测试用例(1) a 6, b 8(2) a = 8(3) a = 6, b =6, b = 8(1) a = 7, b = 7, c = 6(2) a = 5, b = 7, c = 6(3) a = 5, b = 7, c = 6(4) a = 5, b = 7, c = 61. 语句覆盖语句覆盖 a = 5, b = 5, nR
14、eturn = 11语句覆盖率语句覆盖率100%2. 判定覆盖判定覆盖 a = 5, b = 5, nReturn = 11 a = 15, b = 15 nReturn = 0 判定覆盖率判定覆盖率100%3. 条件覆盖条件覆盖 a = 5, b = 15 nReturn = 1 a = 15, b = 5 nReturn = 10条件覆盖率条件覆盖率100% 上面三种覆盖率都达到了上面三种覆盖率都达到了100%,很好!但是,仔细分析可,很好!但是,仔细分析可以看出,以看出,nReturn的结果一共有四种可能的返回值:的结果一共有四种可能的返回值:0、1、 10、11, 而上面每种测试方式只
15、覆盖了部分返回值,可见而上面每种测试方式只覆盖了部分返回值,可见以上任一覆盖方式虽然覆盖率很高,但是并没有测试完全。以上任一覆盖方式虽然覆盖率很高,但是并没有测试完全。 int foo(int a, int b)int nReturn = 0;if (a 10)nReturn += 1; / 分支一分支一if (b 10) nReturn += 10; / 分支二分支二return nReturn;6 路路 径径 覆覆 盖盖Path Coverage 设计设计足够多的测试用足够多的测试用例,使程序的每一条可能例,使程序的每一条可能路径都至少执行一次。路径都至少执行一次。路路 径径 覆覆 盖盖路
16、径路径覆盖将所有可能的返回值都测试到覆盖将所有可能的返回值都测试到了,这正了,这正是是它被很多人认为是它被很多人认为是“最强的覆盖最强的覆盖”的的原因。原因。 int foo(int a, int b)int nReturn = 0;if (a 10)nReturn += 1; / 分支一分支一if (b 1AND B=0TA=2OR X 1TX = X / AX = X + 1返回返回FF1423六种形式的六种形式的逻辑覆盖逻辑覆盖 各种测试方法都不能保证程序的正确性,各种测试方法都不能保证程序的正确性,但测试的目的但测试的目的并不是为了保证并不是为了保证其其正确,而是正确,而是为了尽可能为
17、了尽可能找出程序中隐藏的故障。找出程序中隐藏的故障。语句覆盖语句覆盖判定覆盖判定覆盖条件覆盖条件覆盖判定条件覆盖判定条件覆盖条件组合覆盖条件组合覆盖路径覆盖路径覆盖 (e)两个串行的两个串行的分支结构的分支结构的N-S图图ABPYNAB当当PS S当当P(a)顺序型顺序型(b)选择型选择型(c)Do-While型型(d)Do-Until型型P2YNcdP1YNabN-S图表示的基本控制结构图表示的基本控制结构最少测试用例数最少测试用例数=(5*3+1)*3=486YN7YN2NY3NNNYYY451NY8YN9YN1NY2NY3NNNYYY456YN7YN8YN9YN533白盒测试基本概念白盒
18、测试基本概念1逻辑覆盖逻辑覆盖2基本路径测试基本路径测试3循环测试循环测试4面向对象的白盒测试面向对象的白盒测试5其他白盒测试方法简介其他白盒测试方法简介6主主要要内内容容第四章第四章 白盒测试方法白盒测试方法基本路径测试基本路径测试又称独立路径测试,是指在程序控制流图的基础又称独立路径测试,是指在程序控制流图的基础上,分析控制构造的环路复杂性,导出独立可执上,分析控制构造的环路复杂性,导出独立可执行路径集合,设计测试用例的方法。行路径集合,设计测试用例的方法。设计出的测试用例要保证在测试中,程序的每一设计出的测试用例要保证在测试中,程序的每一个独立可执行路径至少要执行一次。循环体最多个独立可
19、执行路径至少要执行一次。循环体最多只执行一次。只执行一次。 path1:1 11 path2:1 - 2 - 3 - 4 - 5 - 10 - 1 11 path3:1 - 2 - 3 - 6 - 8 - 9 - 10 - 1 11 path4:1 - 2 - 3 - 6 - 7 - 9 - 10 - 1 - 11基本路径集基本路径集1.导出程序流程图的导出程序流程图的拓扑结构拓扑结构流流图图(控制流程图)(控制流程图)2.计算流图的环路复杂性计算流图的环路复杂性3.确定只包含独立路径的基本路径集确定只包含独立路径的基本路径集4.设计测试用例设计测试用例基本(独立)路径测试步骤基本(独立)路径
20、测试步骤int test2( int x, int y ) int k = 0; if (x 0) if ( y = 0 ) k = x + 100; else if ( y = 1 ) k = k + 10; else k = 20; return k; 基基本本路路径径测测试试int test2( int x, int y ) int k = 0; if (x 0) if ( y = 0 ) k = x + 100; else if ( y = 1 ) k = k + 10; else k = 20; / if ( y = 0 ) / if( x0 ) return k; 第一步:第一步:
21、给程序语给程序语句编号句编号第二步:画第二步:画出程序流图出程序流图路径路径1: 1, 2, 10路径路径2:1,2,3,4,10路径路径3:1,2,3,5,6,7,10路径路径4:1,2,3,5,6,8,9,10第三步:找第三步:找出基本路径出基本路径测试用例测试用例:x 0 , y=0, k=x+100测试用例测试用例:x0, y=1, k=10测试用例测试用例:x0, y!= 0, y!=1, k=20第四步:设第四步:设计测试用例计测试用例环路复杂度为环路复杂度为4第三步:计算第三步:计算环路复杂度环路复杂度int test(int x, int y) int k = 0; if( x
22、 0) if( y = 0 ) k = x + 100; else if ( y = 1 ) k += 10; else k = 20; return k; 白盒测试基本概念白盒测试基本概念1逻辑覆盖逻辑覆盖2基本路径测试基本路径测试3循环测试循环测试4面向对象的白盒测试面向对象的白盒测试5其他白盒测试方法简介其他白盒测试方法简介6主主要要内内容容第四章第四章 白盒测试方法白盒测试方法循循 环环 测测 试试简单循环简单循环串接循环串接循环嵌套循环嵌套循环跳过循环跳过循环只通过循环一次只通过循环一次通过循环两次通过循环两次通过循环通过循环m次,其中次,其中m n-1通过循环通过循环n1,n,n+
23、1次次简单循环测试简单循环测试注注: n是允许通过循环的最大次数是允许通过循环的最大次数 嵌套循环测试嵌套循环测试对最内层循环做简单循环的全部对最内层循环做简单循环的全部测试。所有其它层的循环变量置测试。所有其它层的循环变量置为最小值。为最小值。逐步外推,对其外面一层循环进逐步外推,对其外面一层循环进行测试。测试时保持所有外层循行测试。测试时保持所有外层循环的循环变量取最小值,所有其环的循环变量取最小值,所有其它嵌套内层循环的循环变量取它嵌套内层循环的循环变量取“典型典型”值。值。反复进行,直到所有各层循环测反复进行,直到所有各层循环测试完毕。试完毕。对全部各层循环同时取最小循环对全部各层循环
24、同时取最小循环次数,或者同时取最大循环次数次数,或者同时取最大循环次数串接串接循环测试循环测试如果串接循环的各个循环都如果串接循环的各个循环都彼此独立,则可以使用简单彼此独立,则可以使用简单循环的方法来测试串接循环。循环的方法来测试串接循环。当循环不独立时,使用测试当循环不独立时,使用测试嵌套循环的方法来测试串接嵌套循环的方法来测试串接循环。循环。 白盒测试基本概念白盒测试基本概念1逻辑覆盖逻辑覆盖2基本路径测试基本路径测试3循环测试循环测试4面向对象的白盒测试面向对象的白盒测试5其他白盒测试方法简介其他白盒测试方法简介6主主要要内内容容第四章第四章 白盒测试方法白盒测试方法面向对象的白盒测试
25、面向对象的白盒测试类测试一般有两种主要的方式:功能性测试和结类测试一般有两种主要的方式:功能性测试和结构性测试,即对应于传统结构化软件的黑盒测试构性测试,即对应于传统结构化软件的黑盒测试和白盒测试。和白盒测试。结构性测试要考虑程序的代码是否正确,对类中结构性测试要考虑程序的代码是否正确,对类中的方法进行测试,它把类作为一个单元来进行测的方法进行测试,它把类作为一个单元来进行测试。测试分为两层:第一层考虑类中各独立方法试。测试分为两层:第一层考虑类中各独立方法的代码;第二层考虑方法之间的相互作用。的代码;第二层考虑方法之间的相互作用。对于一个类的测试要保证类在其状态的代表集上对于一个类的测试要保
26、证类在其状态的代表集上能够正确工作,构造函数的参数选择以及消息序能够正确工作,构造函数的参数选择以及消息序列的选择都要满足这一准则。列的选择都要满足这一准则。面向对象的白盒测试面向对象的白盒测试方法的单独测试方法的单独测试 结构性测试的第一层是考虑各独立的方法,结构性测试的第一层是考虑各独立的方法,这可以与过程的测试采用同样的方法,两者这可以与过程的测试采用同样的方法,两者之间最大的差别在于方法改变了它所在实例之间最大的差别在于方法改变了它所在实例的状态,这就要取得隐藏的状态信息来估算的状态,这就要取得隐藏的状态信息来估算测试的结果,传给其它对象的消息被忽略,测试的结果,传给其它对象的消息被忽
27、略,而以桩来代替,并根据所传的消息返回相应而以桩来代替,并根据所传的消息返回相应的值,测试数据要求能完全覆盖类中代码,的值,测试数据要求能完全覆盖类中代码,可以用传统的测试技术来获取。可以用传统的测试技术来获取。面向对象的白盒测试面向对象的白盒测试方法的综合测试方法的综合测试 第二层要考虑一个方法调用本对象类中的第二层要考虑一个方法调用本对象类中的其它方法和从一个类向其它类发送信息的其它方法和从一个类向其它类发送信息的情况。单独测试一个方法时,只考虑其本情况。单独测试一个方法时,只考虑其本身执行的情况,而没有考虑动作的顺序问身执行的情况,而没有考虑动作的顺序问题,测试用例中加入了激发这些调用的
28、信题,测试用例中加入了激发这些调用的信息,以检查它们是否正确运行了。对于同息,以检查它们是否正确运行了。对于同一类中方法之间的调用,一般只需要极少一类中方法之间的调用,一般只需要极少甚至不用附加数据,因为方法都是对类进甚至不用附加数据,因为方法都是对类进行存取,故这一类测试的准则是要求遍历行存取,故这一类测试的准则是要求遍历类的所有主要状态。类的所有主要状态。 白盒测试基本概念白盒测试基本概念1逻辑覆盖逻辑覆盖2基本路径测试基本路径测试3循环测试循环测试4面向对象的白盒测试面向对象的白盒测试5其他白盒测试方法简介其他白盒测试方法简介6主主要要内内容容第四章第四章 白盒测试方法白盒测试方法程序插
29、桩方法是借助往被测程序中插入程序插桩方法是借助往被测程序中插入操作来实现测试目的的方法。该法是软操作来实现测试目的的方法。该法是软件动态测试中的一种基本测试手段,有件动态测试中的一种基本测试手段,有着广泛的应用。着广泛的应用。如果我们想要了解一个程序在某次运行如果我们想要了解一个程序在某次运行中所有可执行语句被覆盖的情况,或是中所有可执行语句被覆盖的情况,或是每个语句的实际执行次数,最好的办法每个语句的实际执行次数,最好的办法是利用插桩技术。是利用插桩技术。插插 桩桩 测测 试试 入口 Q=X R=Y QR QR 出口 Q=QR R=RQ 入口 C(1)=C(1)+1 Q=X R=Y C(2)
30、=C(2)+1 C(6)=C(6)+1 QR C(4)=C(4)+1 C(3)=C(3)+1 QR 出口 C(5)=C(5)+1 Q=QR R=RQ 桩桩1桩桩2桩桩3桩桩6桩桩4桩桩5程序插桩时需要着重考虑:程序插桩时需要着重考虑:1.探测哪些信息;探测哪些信息;2.在程序的什么部位设置探测点;在程序的什么部位设置探测点;3.需要设置多少个探测点。需要设置多少个探测点。域测试域测试(Domain Testing)域测试是一种基于程序结构的测试方法。域测试是一种基于程序结构的测试方法。 Howden把程序中出现的错误分为域错误、计算型把程序中出现的错误分为域错误、计算型错误和丢失路径错误三种。
31、错误和丢失路径错误三种。 如果程序的控制流有错误,对于某一特定的输入如果程序的控制流有错误,对于某一特定的输入可能执行的是一条错误路径,这种错误称为路径可能执行的是一条错误路径,这种错误称为路径错误,也叫做域错误。错误,也叫做域错误。如果对于特定输入执行的是正确路径,但由于赋如果对于特定输入执行的是正确路径,但由于赋值语句的错误致使输出结果不正确,则称此为计值语句的错误致使输出结果不正确,则称此为计算型错误。算型错误。另外一类错误是丢失路径错误。另外一类错误是丢失路径错误。 域测试是主要针对域错误进行的程序测试。域测试是主要针对域错误进行的程序测试。域测试方法基于对输入空间的分析。域测试方法基
32、于对输入空间的分析。 测试的理想结果就是检验输入空间中的每一个输测试的理想结果就是检验输入空间中的每一个输入元素是否都产生正确的结果。入元素是否都产生正确的结果。 域测试正是在分析输入域的基础上,选择适当的域测试正是在分析输入域的基础上,选择适当的测试点以后进行测试的。测试点以后进行测试的。域测试有两个致命的弱点:一是为进行域测试对域测试有两个致命的弱点:一是为进行域测试对程序提出的限制过多,二是当程序存在很多路径程序提出的限制过多,二是当程序存在很多路径时,所需的测试点也很多。时,所需的测试点也很多。 域测试域测试(Domain Testing)符号测试方法符号测试方法基本思想是允许程序的输
33、入不仅仅是具体的数基本思想是允许程序的输入不仅仅是具体的数值数据,而且包括符号值,符号值可是基本符值数据,而且包括符号值,符号值可是基本符号变量值,也可是这些符号变量值的一个表达号变量值,也可是这些符号变量值的一个表达式。式。普通测试执行的是算术运算,符号测试则是执普通测试执行的是算术运算,符号测试则是执行代数运算。行代数运算。 符号测试方法使用问题的关键在于开发出比传符号测试方法使用问题的关键在于开发出比传统的编译器功能更强,能够处理符号运算的编统的编译器功能更强,能够处理符号运算的编译器和解释器。译器和解释器。 Z路径覆盖测试方法路径覆盖测试方法称简化循环意义下的路径覆盖为称简化循环意义下的路径覆盖为Z路径覆盖。路径覆盖。 即无论循环的形式和实际执行循环体的次数多即无论循环的形式和实际执行循环体的次数多少,我们只考虑循环一次和零次两种情况。少,我们只考虑循环一次和零次两种情况。 (a) (b) (c) Any Questions