白盒测试及其用例的设计.ppt_第1页
白盒测试及其用例的设计.ppt_第2页
白盒测试及其用例的设计.ppt_第3页
白盒测试及其用例的设计.ppt_第4页
白盒测试及其用例的设计.ppt_第5页
已阅读5页,还剩77页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

,教学目标,理论环节 学习理解白盒测试方法的基本概念 学习理解白盒测试的覆盖理论 学习掌握白盒测试的路径表达 学习掌握白盒测试的基本路径测试法 实践环节 通过案例运用学习掌握覆盖问题的解决方法 运用基本路径测试方法进行实际程序测试,白盒测试也称结构测试或逻辑驱动测试,是针对被测单元内部是如何进行工作的测试。白盒法把测试对象看做是一个打开的盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致。,白盒法也不可能进行穷举测试,企图遍历所有的路径,往往是做不到的。,左图所示的一个小程序的控制流程,其中每个圆圈代表一段源程序(或语句块),图中的曲线代表执行次数不超过20的循环,循环体中共有5条通路。这样,可能执行的路径有520条,近似为1014条可能的路径。如果完成一个路径的测试需要1毫秒,那么整个测试过程需要3170年。显然,这也是不能接受的。,白盒法需要了解程序的内部结构和详细的处理过程,它按照程序内部逻辑测试程序,检验程序中每条通路是否按预定要求正确工作。,对于白盒测试,即使每条路径都测试了,程序仍可能有错。再如由于疏忽漏写了路径,白盒测试也发现不了。 所以,白盒法不能使测试达到彻底。为了用有限的测试发现更多的错误,需精心设计测试用例。黑盒法、白盒法是设计测试用例的基本策略,每一种方法对应着多种设计测试用例的技术,每种技术可达到一定的软件质量标准要求。,测试用例的设计,白盒技术,在测试阶段穷举测试不可行,必须要从数量极大的可用测试用例中精心地挑选少量的测试数据,使得采用这些测试数据能够达到最佳的测试效果,能够高效率地把隐藏的错误揭露出来。下面介绍几种白盒测试设计测试用例的方法。,白盒测试的主要方法,逻辑驱动测试 基本路径测试 主要用于软件验证。 使用程序设计的控制结构导出测试用例。,全部例子均为C语言编制,六种逻辑覆盖,一个显而易见的问题:一个完整的语句,未必是一行语句,y=abs(x); if (x=0) y=sqrt(x); if (x=0) y=x; else y=abs(x); if (x=0),简单的赋值语句,单分支语句,双分支语句,判断条件较复杂的单分支语句,一些更复杂的语句,if (x100) printf(“ERROR!“); else if(x=60) printf(“OK!“); else printf(“FAIL!“); for(i=0;i10;i+) s=s+ai;,判断条件较复杂的多分支语句,简单的循环语句,对以上语句,请思考:如何让它们都被执行?,简单的赋值语句 使赋值号左侧的变量得到一个值 分支语句 使各个分支语句中至少一个被执行 循环语句 使循环体被执行至少一次,Q:什么叫做“语句被执行”?,给出测试数据,使各语句均被执行,y=abs(x); if (x=0) y=sqrt(x); if (x=0) y=x; else y=abs(x);,令x任取一值即可使本语句被执行,令x任取一非负数值即可保证判断条件成立,语句被执行,令x任取一值,因为此二分支覆盖了全部的取值范围,x无论取什么值,都能使其中的一个分支被执行,if (x=0)|(z=0) y=x*z;,不管z,令x任取一非负数值,不管x,令z任取一非负数值,令x、z同时任取一非负数值,这三种取值均能使判断条件成立,令判断条件成立,语句即被执行,if (x100) printf(“ERROR!“); else if(x=60) printf(“OK!“); else printf(“FAIL!“);,令判断条件A成立,分支之一被执行,令判断条件A不成立,但B成立,那么分支之二被执行,令判断条件AB均不成立,则分支之三被执行,A,B,以上三种取值,均能使这个分支语句得以执行,for(i=0;i10;i+) s=s+ai;,令 i 取零到9闭区间内的任意值,循环体就会被执行,可见:越复杂、影响最终结果的变量的可能值越多的语句,只要取其任一个分支或任一种可能,整条语句就算被执行,最彻底的测试,是考虑到每一种可能,最粗略的测试,是仅仅考虑到其中的一种可能,逻辑驱动测试,是以程序内在逻辑结构为基础的测试,即测试覆盖率。共包括以下 6 种类型(强弱程度逐渐递增): 语句覆盖 判定覆盖 条件覆盖 判定-条件覆盖 条件组合覆盖 路径覆盖,考虑到每一种可能,最彻底,仅考虑一种可能,最粗略,void DoWork1(int x) 1 2 int k=0,j=0; 3 if(x3) /语句1 4 k=x3-1; 5 j=sqrt(k); /语句2 6 printf(“%d,%5.2dn“,k,j); 7 ,如下的C函数:,Q1:本函数中起作用的变量有哪几个? x Q2:用最简单的输入,使函数中的每个语句都得到执行:令x为4,单分支语句,void DoWork(int x,int y,int z) 1 2 int k=0,j=0; 3 if(x3) /语句2 9 ,如下的C函数:,Q1:本函数中起作用的变量有哪几个?x、y、z Q2:用最简单的输入,使函数中的每个语句都得到执行 x=4 同时 z=9,判断条件较复杂的单分支语句,void DoWork2(int x) 1 2 int k=0,j=0; 3 if(x3) /语句1 4 k=x-1; 5 else 6 k=sqrt(x); ,如下的C函数:,Q1:本函数中起作用的变量有哪几个? Q2:用最简单的输入,使函数中的每个语句都得到执行 x为4 Q3:使函数中的每个语句都得到最充分的执行 用例1:x为4 用例2:x为3,双分支语句,概 念,语句覆盖:使得每一条可执行语句至少执行一次 判定覆盖(也称为分支覆盖):使程序中每个判断的取真分支和取假分支至少执行一次 条件覆盖:使程序中每个判断的每个条件的每个可能取值至少执行一次 判定-条件覆盖:使程序中每个判断的每个条件的所有可能取值至少执行一次,并且每个可能的判断结果也至少执行一次,换言之,即是要求各个判断的所有可能的条件取值组合至少执行一次 条件组合覆盖:使程序中每个判断的所有可能的条件取值组合至少执行一次 路径覆盖:要覆盖程序中所有可能的路径,设计若干个测试用例,运行被测试程序,各种逻辑覆盖的概念介绍,语句覆盖:设计若干个测试用例,运行被测试程序,使得每一条可执行语句至少执行一次;,但其覆盖标准无法发现判定中逻辑运算的错误;,此方法是把程序中的所有的语句都覆盖到;,if (x=0) y=x; else y=abs(x);,x=abs(x);,if (x=0) y=x;,else y=abs(x);,一个用例即可:x为0,一个用例即可:x为0,判定覆盖(也称为分支覆盖):设计若干个测试用例,运行所测程序,使程序中每个判断的取真分支和取假分支各至少执行一次;,(x3)&(z10)为真和为假各取一次(但并不管是怎么取到的),判定覆盖是把程序中每个分支都覆盖到;,但当判断条件较为复杂时,它未必能发现每个条件的错误:,if (x=0) y=x; else y=abs(x);,if (x=0) y=x;,else y=abs(x);,对程序中的双分支语句,相当于覆盖了两次,第1个用例:x为0,第2个用例:x为-1,这个分支语句中,判断就是条件,条件就是判断,if(x3)|(z3)|(z3)和(z10)分别是构成这个判断的两个条件,判断的结果真假取决于这两个条件的值分别是真还是假,何谓判断?何谓条件?,if (x=0) y=x; else y=abs(x);,if(x3)|(z10) else ,这个分支语句中,判断取决于两个条件,这两个条件的真假和判断的真假未必一致,条件覆盖:设计足够多的测试用例,运行所测程序,使程序中每个判断的每个条件的每个可能取值至少执行一次;,(x3)为真和假各取一次;(z3)|(z10)这个整体的真假就没有提及),条件覆盖是把判断中所有的条件都覆盖到;,但它未必能覆盖全部分支;,if(x3)|(z3)|(z3)和(z10)分别是构成这个判断的两个条件,判断的结果真假取决于这两个条件的值分别是真还是假,何谓判断?何谓条件?,也只有在判断条件较复杂时,2和3才有区别,if(x3)|(z10) else ,第3个用例:z为9,第4个用例:z为11,2.判定覆盖,3.条件覆盖,第1个用例:x为4,第2个用例:x为2同时z为11,第1个用例:x为4,第2个用例:x为2,if(x3)|(z10) else ,判定-条件覆盖:设计足够多的测试用例,运行所测程序,使程序中每个判断的每个条件的所有可能取值至少执行一次,并且每个可能的判断结果也至少执行一次;,(x3)为真和假各取一次;(z3)|(z10)为真和为假各取一次,即: (x3)和(z3)和(z10)同时为假取一次; 就可以满足,if(x3)|(z10) else ,继续对比2、3、4的区别,第3个用例:z为9,第4个用例:z为11,2.判定覆盖,4.判断-条件覆盖,第1个用例:x为4,第2个用例:x为2同时z为11,第1个用例:x为4,第2个用例:x为2,if(x3)|(z10) else ,第3个用例:z为9,第4个用例:z为11,3.条件覆盖,第1个用例:x为4,第2个用例:x为2,第6个用例:x为2同时z为11,第5个用例:x为4,(以上用例可以缩减),条件组合覆盖:设计足够多的测试用例,运行所测程序,使程序中每个判断的所有可能的条件取值组合至少执行一次;,把(x3)和(z10)为真和为假的各种可能组合各执行一次,即: (x3)和(z3)和(z3)和(z3)和(z10)分别为假真取一次; 才能满足,if(x3)|(z3)|(z3)和(z10)分别是构成这个判断的两个条件,判断的结果真假取决于这两个条件的值分别是真还是假,何谓判断?何谓条件?,继续对比4、5的区别,第3个用例:x为4同时z为11,第4个用例:x为2同时z为9,5.条件组合覆盖,第1个用例:x为4同时z为9,第2个用例:x为2同时z为11,if(x3)|(z10) else ,第3个用例:z为9,第4个用例:z为11,4.判定-条件覆盖,第1个用例:x为4,第2个用例:x为2,第5个用例:x为2同时z为11,真真、假假、真假、假真,路径覆盖:设计足够多的测试用例,运行所测程序,要覆盖程序中所有可能的路径 它是最强的覆盖准则,但只有在程序中有多个复杂分支时,才能看出和之前几种覆盖的区别,void DoWork(int x,int y,int z) int k=0,j=0; if(x3) /语句块3 ,函数的流程图,语句覆盖,为了说明简略,分别对各个判断的取真、取假分支 编号为b、c、d、e。 为了测试语句覆盖率只要设计一个测试用例 就可以把三个执行语句块中的语句覆盖了。 测试用例输入为:x=4、y=5、z=5 程序执行的路径是:abd,该测试用例虽然覆盖了每条可执行语句,但并不能检查判断逻辑是否有问题,例如在第一个判断中把&错误的写成了|,则上面的测试用例仍可以覆盖所有的执行语句(即查不出写错了这个事实)可以说语句覆盖率是最弱的逻辑覆盖准则,使程序中每个语句至少执行一次,判定覆盖,对于上面的程序,如果设计两个测试用例则可以满足分支覆盖的要求。 测试用例的输入为: x=4、y=5、z=5 abd x=2、y=5、z=5 ace 上面的两个测试用例虽然能够满足分支覆盖的要求,但是也不能实现对判断条件的检查效果,如果把第二个条件y5错误地写成y5,上面的测试用例同样满足了分支覆盖(即查不出写错了这个事实),使程序中每个判断的取真分支和取假分支至少执行一次,条件覆盖,就是设计若干个测试用例,运行被测试对象,使得程序中每个判断的每个条件的所有可能取值至少执行一次。 对例子中的所有条件取值加以标记。例如: 对于第一个判断: 条件1:x3 取真值为T1,取假值为-T1 条件2:z5 取真值为T4,取假值为-T4,使程序中每个判断每个条件分别取真和取假各一次,可以设计测试用例如下:,上面的测试用例不但覆盖了所有分支的真假两个分支,而且覆盖了判断中的所有条件的可能值,如果设计了下面的测试用例,则虽然满足了条件覆盖,但只覆盖了第一个条件的取假分支和第二个条件的取真分支,又不满足分支覆盖的要求(be线路未执行),使程序中每个判断的取真分支和取假分支至少执行一次,需要改进:即判定-条件覆盖,判定-条件覆盖,判定-条件覆盖就是设计足够的测试用例,使得判断中每个条件的所有可能取值至少执行一次,同时每个判断的所有可能判断结果至少执行。 根据定义只需设计以下两个测试用例便可以覆盖8个条件值以及4个判断分支。,判定-条件覆盖从表面来看,测试了所有条件的取值,但实际上,某些条件掩盖了另一些条件,即仍然有遗漏。 例如:对于条件表达式(x3)&(z3)为假,则一般的编译器将不再判断是否(z5)来说,若x=4测试结果为真,就认为表达式的结果为真,这时不再检查(y5)是否为真。 可见,采用判定-条件覆盖,逻辑表达式中的错误不一定都能查出来。,条件组合覆盖:,条件组合覆盖就是设计足够的测试用例,运行被测试对象,使得每一个判断的所有可能的条件取值组合至少执行一次。 现在对例子中的各个判断的条件取值组合加以标记如下: x3,z3,z=10 记做T1 -T2, 第一个判断的取假分支 x=10 记做-T1 -T2,第一个判断的取假分支 x=4,y5 记做T3 T4, 第二个判断的取真分支 x=4,y5 记做-T3 T4, 第二个判断的取真分支 x!=4,y=5 记做-T3 -T4,第二个判断的取假分支,判定-条件覆盖使得判断中每个条件的所有可能取值至少执行一次, 同时每个判断的所有可能判断结果至少执行一次,if(x3)&(z5),根据定义取4个测试用例,就可以覆盖上面8种条件取值的组合测试用例。如下表:,上面的测试用例覆盖了所有条件的可能取值的组合,覆盖了所有判断的可取分支,但却丢失了路径abe,路径覆盖,路径覆盖就是设计足够多的测试用例,覆盖被测试对象中的所有可能路径 在上面的测试用例中再添加一个测试用例,则可对程序进行全部的路径覆盖,路径覆盖,分析: 虽然前面一组测试用例满足了路径覆盖,但并没有覆盖程序中所有的条件组合,即满足路径覆盖的测试用例并不一定满足组合覆盖。,路径覆盖,说明: 对于比较简单的小程序,实现路径覆盖是可 能做到的。但如果程序中出现较多判断和较 多循环,可能的路径数目将会急剧增长,要 在测试中覆盖所有的路径是无法实现的。为 了解决这个难题,只有把覆盖路径数量压缩 到一定的限度内,如程序中的循环体只执行 一次。,路径覆盖,在实际测试中,即使对于路径数很有限的程 序已经做到路径覆盖,仍然不能保证被测试 程序的正确性,还需要采用其他测试方法进 行补充。,对这个C函数分别作六种覆盖,Main() int a,b; float c; if(a0) /语句块3 ,6种覆盖标准的对比,语句覆盖发现错误能力最弱。判定覆盖包含了语句覆盖,但它可能会使一些条件得不到测试。条件覆盖对每一条件进行单独检查,一般情况下它的检错能力较判定覆盖强,但有时达不到判定覆盖的要求。判定/条件覆盖包含了判定覆盖和条件覆盖的要求,但由于计算机系统软件实现方式的限制,实际上不一定达到条件覆盖的标准。条件组合覆盖发现错误能力较强,凡满足其标准的测试用例,也必然满足前4种覆盖标准。,前5种覆盖标准把注意力集中在单个判定或判定的各个条件上,可能会使程序某些路径没有执行到。路径测试根据各判定表达式取值的组合,使程序沿着不同的路径执行,查错能力强。但由于它是从各判定的整体组合出发设计测试用例的,可能使测试用例达不到条件组合覆盖的要求。在实际的逻辑覆盖测试中,一般以条件组合覆盖为主设计测试用例,然后再补充部分用例,以达到路径覆盖测试标准。,练习题:为以下流程图所示的程序段设计一组测试用例,要求分别满足语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖和路径覆盖。,一个被测试程序的流程图,作业题,作业题,试做出左边三角形问题的语句覆盖,条件覆盖,判定覆盖,判定条件覆盖、组合条件覆盖的测试用例.并注明满足覆盖的条件.eg: a b c 3 4 5 T1T2T3F4F5F6,基本路径测试,基本路径测试,基本路径测试法是在程序控制流图的基础上, 通过分析控制构造的环路复杂性,导出基本可 行路径的集合,从而设计测试用例的方法。设 计出的测试用例要保证被测试程序的每个可执 行语句至少执行一次。 完成路径测试的理想情况是做到路径覆盖, 但对于复杂性大的程序要做到所有路径覆盖 是不可能的。,基本路径测试,在不能做到所有路径覆盖的前提下,如 果某一程序的每一个独立路径都被测试 过,那么可以认为程序中的每个语句都 已经检验过了,即达到了语句覆盖。这 种测试方法就是通常所说的基本路径测 试方法。,void DoWork(int x,int y,int z) int k=0,j=0; if(x3) /语句块3 ,函数的流程图,基本路径测试,这个例子是一个很简单的程序函数,只有四条路径。但在实践中,一个不太复杂的程序,其路径都是一个庞大的数字,要在测试中覆盖所有的路径是不现实的。,为了解决这一难题,只得把覆盖的路径数压缩到一定限度内,例如,程序中的循环体只执行一次。 基本路径测试就是这样一种测试方法,它在程序控制图的基础上,通过分析控制构造的环行复杂性,导出基本可执行路径集合,从而设计测试用例的方法。 设计出的测试用例要保证在测试中程序的每一个可执行语句至少执行一次。,在介绍基本路径方法之前,必须先介绍一种简单的控制流表示方法,即流图。,控制流图(可简称流图)是对程序流程图进行简化后得到的,它可以更加突出的表示程序控制流的结构。 控制流图中包括两种图形符号:节点和控制流线。 节点由带标号的圆圈表示,可代表一个或多个语句、一个处理框序列和一个条件判定框(假设不包含复合条件)。 控制流线由带箭头的弧或线表示,可称为边。它代表程序中的控制流。 对于复合条件,则可将其分解为多个单个条件,并映射成控制流图。,常见结构的控制流图,常见结构的控制流图,其中,包含条件的节点被称为判定节点(也叫谓词节点),由判定节点发出的边必须终止于某一个节点,由边和节点所限定的范围被称为区域。,1. 程序的控制流图,1. 程序的控制流图,区域,程序的控制流图,如果判断中的条件表达式是由一个或多 个逻辑运算符 ( |, &, .) 连接的复合 条件表达式,则需改为 一系列只有单个 条件的嵌套的判断。,程序的控制流图,if(a|b) 执行x; else 执行y;,1. 程序的控制流图,复合条件下的控制流图 (a) 程序;(b) 控制流图,基本路径测试,基本路径测试方法是在控制流图的基础上,通过分析控制结构的环形复杂度,导出执行路径的基本集合,再从该基本集设计测试用例。基本路径测试方法包括4个步骤:,基本路径测试,(1)画出程序的控制流图。 (2)计算程序的环形复杂度,导出程序基本路径集中的独立路径条数,这是确定程序中每个可执行语句至少执行一次所必须的测试用例数目的上界。,基本路径测试,(3)导出基本路径集,确定程序的独立路径。 (4)根据(3)中的独立路径,设计测试用例的输入数据和预期输出。,第一步:画出控制流图,c/c+语句中的控制语句表示含义如下: 图中的每一个圆称为流图的结点,代表一条或多条语句。流图中的箭头称为边或连接,代表控制流。 为了说明流图的用法,我们采用过程设计表示法,此处,流程图用来描述程序控制结构。可将流程图映射到一个相应的流图(假设流程图的菱形决定框中不包含复合条件)。在流图中,每一个圆,称为流图的结点,代表一个或多个语句。一个处理方框序列和一个菱形决测框可被映射为一个结点,流图中的箭头,称为边或连接,代表控制流,类似于流程图中的箭头。一条边必须终止于一个结点,即使该结点并不代表任何语句(例如:参见if-else-then结构的符号)。由边和结点限定的范围称为区域。计算区域时应包括图外部的范围。 任何过程设计都要被翻译成控制流图。,void Sort(int iRecordNum,int iType) 1 2 int x=0; 3 int y=0; 4 while (iRecordNum- 0) 5 6 if(iType= =0) 7 x=y+2; 8 else 9 if(iType= =1) 10 x=y+10; 11 else 12 x=y+20; 13 14 ,如下面的C函数:,在将程序流程图简化成控制流图时,应注意: 在选择或多分支结构中,分支的汇聚处应有一个汇聚结点。 边和结点圈定的区域叫做区域。 当对区域计数时,图形外的区域也应记为一个区域。,如何根据程序流程图画出控制流程图 ?,void Sort(int iRecordNum,int iType) 1 2 int x=0; 3 int y=0; 4 while (iRecordNum- 0) 5 6 if(iType= =0) 7 x=y+2; 8 else 9 if(iType= =1) 10 x=y+10; 11 else 12 x=y+20; 13 14 ,画出其程序流程图如下:,void Sort(int iRecordNum,int iType) 1 2 int

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论