关闭

关闭

关闭

封号提示

内容

首页 测试用例设计方法.ppt

测试用例设计方法.ppt

测试用例设计方法.ppt

上传者: 梦之冰蓝 2012-08-25 评分 0 0 0 0 0 0 暂无简介 简介 举报

简介:本文档为《测试用例设计方法ppt》,可适用于IT/计算机领域,主题内容包含测试用例设计方法测试用例设计方法主要内容主要内容功能性测试设计结构性测试设计状态转换测试设计OO单元测试设计参考书《软件测试(原书第二版)(Soft符等。

测试用例设计方法测试用例设计方法主要内容主要内容功能性测试设计结构性测试设计状态转换测试设计OO单元测试设计参考书《软件测试(原书第二版)(SoftwareTestingAcraftsman‘sApproachSecondEdition)美PaulCJorgensen著韩柯杜旭涛翻译机械工业出版社《软件工程-实践者的研究方法》(SoftwareEngineeringApractitioner‘sApproachFifthEdition)RogerSPressman,黄伯素梅宏翻译机械工业出版社《嵌入式软件测试》(TestingEmbededSoftware)美BartBorekman,EdwinNotenboom著张君施张思宇周承平译电子工业出版社测试用例设计方法概述测试用例设计方法概述测试用例设计方法主要分两大类:黑盒测试(功能性测试)和白盒测试(结构性测试)它们使用的测试用例在表现形式上一模一样都是:(输入输入……输入n预期输出)这输入输入……输入n就是程序的输入(可以理解为程序的输入参数全局变量触发事件)预期输出可以是程序的输出(可理解为程序的输出参数返回值全局变量输出事件)如右图程序的规格说明(预期行为)和内部结构(决定实际行为)黑盒测试与白盒测试的区别在于黑盒测试方法通过程序的规格说明来识别测试用例。白盒测试根据程序的内部代码结构(分支循环条件)来识别测试用例见右图黑盒测试与白盒测试的结合黑盒测试与白盒测试的结合基于黑盒的测试(也就是基于规格说明测试)可能有些程序的内部路径(大多数是些异常处理路径)覆盖不到往往是这里的代码会使程序表现出大家所不期望的行为(程序异常死机或隐藏了恶意的代码如特洛伊木马程序还有内存泄漏程序走飞死循环等等)。所以有必要在黑盒测试结束后检查一下程序内部的测试覆盖率对没有覆盖到的路径或代码根据代码结构信息再设计一些测试用例覆盖这些没有覆盖到路径或代码看看程序是否会出现异常的行为。这是我们所倡导的基本的软件单元测试策略。两个示例程序两个示例程序三角形问题NextDate问题三角形问题陈述三角形问题陈述三角形问题接受三个整数ab和c作为输入用做三角形的的边。程序的输出是由这三条边确定的三角形类型:等边三角形等腰三角形不等边三角形或非三角形。NextDate问题NextDate问题NextDate是一个有三个变量(月份日期和年)的函数。函数返回输入日期后面的那个日期。变量月份日期和年都具有整数值且满足下列条件:C:<=月份<=C:<=日期<=C:<=年<=如果任意一个条件失败则NextDate会出示一个消息指示相应的变量超出范围功能性测试设计功能性测试设计边界值测试等价类测试决策表测试边界值测试边界值测试任何程序都可以看做是一个函数程序的输入构成函数的定义域程序的输出构成函数的值域输入定义域测试是最著名的功能性测试手段它的重点是在输入定义域边界值分析健壮性测试最坏情况测试特殊值测试边界值分析边界值分析大量的错误是发生在输入或输出范围的边界上而不是在输入范围的内部。针对各种边界情况设计测试用例可以查出更多的错误。边界值分析的基本思想是使用在最小值略高于最小值正常值略低于最大值和最大值处取输入变量值边界值分析基于单缺陷假设:失效极少是由两个(或多个)参数同时取某一特定值引起的,基本是由单变量取某一特定值引起的边界值测试用例的获得:通过所有变量取正常值只有一个变量取边界值。<xnom,xmin>,<xnom,xmin>,<xnom,xnom>……<xnom,xmax>共个测试用例变量是离散有界值都可以用边界值分析但逻辑布尔量不适用(如电话号码)边界值分析举例边界值分析举例在描述问题时,关于三角形的边,除了说明是整数外,没有给出其他条件显然,低端边界都是我们任意取做为高端边界,下表给出使用这些定义域产生的边界测试用例健壮性测试健壮性测试健壮性测试是边界值分析的一种简单扩展:除了变量的五个边界值分析取值还要通过采用一个略超过最大值(max+)的取值和一个略小于最小值(min-)的取值如果程序执行显式的范围检查并适用例外处理机制解决“健壮值”问题必须选择健壮性测试最坏情况测试最坏情况测试最坏情况测试拒绝单缺陷假设,采用多缺陷假设:某些失效(Failure)是由两个或多个参数同时取某些特定值引起的对每个变量首先进行包含最小值略高于最小值正常值略低于最大值最大值五元素测试然后对这集合进行笛卡尔儿积计算生成测试用例笛卡尔积笛卡尔积两个集合A和B的笛卡尔积是集合AB={<x,y>xЄA^YєB}例:集合A={,,}集合B={w,x,y,z}A和B的笛卡尔积是集合AB={<,w>,<,x>,<,y>,<,z>,<,w>,<,x>,<,y>,<,z>,<,w>,<,x>,<,y>,<,z>}例:一个更直观的例子:x轴上的点与y轴上的点的笛卡尔积是整个平面上所有点的集合。最坏情况测试举例最坏情况测试举例我们仍然以三角形程序举例来说明最坏情况测试特殊值测试特殊值测试当测试人员适用其领域知识适用类似程序的经验以及关于“软点”信息开发测试用例时就会出现特殊值测试就是不使用测试方针只使用“最佳工程判断”特殊值测试是高度主观性的但是所产生的测试用例集合常常比我们已经研究过的其他方法生成的测试集合更能有效地发现缺陷边界值测试总结边界值测试总结除了特殊值测试基于函数(程序)输入定义域的测试方法是所有测试方法中最基本的这些测试方法都有一种假设:即输入变量是真正独立的如果不能保证这种假设就不能产生令人非常满意的测试用例(如NextDate中生成年月日)这些方法还有两方面的区别:正常值和健壮值单缺陷和多缺陷假设等价类测试等价类测试使用等价类作为功能性测试的基础有两个动机:我们希望进行完备的测试同时又希望避免冗余等价类测试重复边界值测试的两个决定因素:健壮性和单多缺陷假设等价类的重要问题是它们构成集合的划分其中划分是指互不相交的一组子集子集的元素都有一些共同的特点等价类测试的思想就是通过每个等价类中的一个元素代表整个等价类元素集合来标识测试用例。等价类测试的关键就是选择类的等价关系。示例函数示例函数我们讨论一个具有两个变量x,x的函数F其中:a<=x<=d,区间为ab)b,c)c,de<=x<=g,区间为e,f)f,gX和x的无效值是:x<a,x>d,和X<eX>g弱一般等价类测试弱一般等价类测试弱一般等价类测试:测试用例中每个参数等价类(区间)的都被遍历到注意单缺陷假设的作用弱一般等价类测试的测试用例的个数等于max(参数等价类个数参数等价类个数……参数n的等价类个数)强一般等价类强一般等价类强一般等价类测试基于多缺陷假设因此测试用例的个数等于各个参数等价类个数的乘积。弱健壮等价类测试弱健壮等价类测试这种测试的名称显然与直觉矛盾而且自相矛盾怎么既弱而且又健壮?健壮是考虑了无效值弱是有单缺陷假设对于有效输入使用等价类的一个值对于无效输入测试用例将拥有一个无效值强健壮等价类测试强健壮等价类测试这种测试名称既不与直觉矛盾也不自相矛盾只是觉得有些冗余健壮是指要考虑无效指强是指多缺陷假设我们从所有等价类的笛卡尔积中获得测试用例三角形问题的等价类测试用例三角形问题的等价类测试用例在描述问题时我们曾经提到过有四种可能出现的输出:非三角形不等边三角形等腰三角形和等边三角形。可以使用这些输出标识如下所示的输出(值域)有效等价类(无效等价类没有列出):R={<a,b,c>:有三条边a,b和c的等边三角形}R={<a,b,c>:有三条边a,b和c的等腰三角形}R={<a,b,c>:有三条边a,b和c的不等边三角形}R={<a,b,c>:三条边a,b和c不构成三角形}一般等价类弱健壮强健壮等价类举例一般等价类弱健壮强健壮等价类举例NextDate问题的等价类测试NextDate问题的等价类测试NextDate是一个三变量函数即月份日期和年这些变量的有效值区间定义如下:M={月份:月份}D={日期:日期}Y={年:年}无效等价类M={月份:月份〈}M={月份:月份〉}D={日期:日期〈}D={日期:日期〉}Y={年:年〈}Y={年:年〉}NextDate问题的等价类测试用例NextDate问题的等价类测试用例NextDate问题的等价类测试(第二次)NextDate问题的等价类测试(第二次)以上只是在有效无效的层次上处理等价类通过对平年和闰年的分析日期是月末最后一天的分析可以对有效值进行进一步区分等价类:M={月份:每月有天}M={月份:每月有天}M={月份:此月是月}D={日期:日期}D={日期:日期=}D={日期:日期=}D={日期:日期=}Y={年:年=}Y={年:年是闰年}Y={年:年是平年}NextDate问题的等价类测试用例NextDate问题的等价类测试用例和以前一样机械地从对应的等价类中间选择输入机械选择输入值不考虑领域知识会出现不可能的输入日期“自动”的测试用例生成永远都会有这种问题因为领域知识不是通过等价类选择获得的。等价类测试的总结等价类测试的总结等价类测试的弱形式不如强形式的测试全面如果输入数据以离散值区间和集合定义则等价类测试是合适的。当然也适用于如果边界值越界系统就会出现故障的系统通过结合边界值测试等价类测试可得到加强在发现“合适”的等价关系之前可能需要进行多次尝试。如果程序函数很复杂则等价类是被暗示的如NextDate函数基于决策表的测试基于决策表的测试在所有功能性测试方法中基于决策表的测试方法是最严格的因为决策表具有逻辑严格性世纪年代初以来,决策表一直被用来表示和分析复杂逻辑关系决策表很适合描述不同条件集合下采取行动的若干组合的情况使用决策表来设计测试用例使用决策表来设计测试用例为了使用决策表标识测试用例,我们把条件解释为输入,把行动解释为输出(第一种方法)有时候条件最终引用输入的等价类,行动引用被测软件的主要功能处理部分这时每条规则就被解释成测试用例的输入(第二种方法)由于决策表可以机械地强制为完备的,因此可以生成用测试用例的完整集合决策表的构成决策表的构成决策表有四部分:条件桩条件条目行动桩和行动条目所有条件都是二叉条件的决策表叫做有限决策表如果条件可以有多个值则对应的决策表叫做扩展条目表三角形问题决策表第一种方法三角形问题决策表第一种方法三角形问题决策表中给出了不关心条目-和不可能规则使用的例子不关心条目实际表明条件是不相关的它代表了多条规则(如果是有限条目决策表则规则中每出现一个不关心条目该规则数乘一次)不可能规则不关心条目条件桩代表测试用例的输入行动桩代表测试用例的输出每条规则标识了一个测试用例NextDate的决策表测试用例NextDate的决策表测试用例前面在讲NextDate的等价类测试中发现从等价类中随意地选取输入值会产生很奇怪的测试用例如年月日的下一天。问题的根源在于假设变量都是很独立的。如果变量确实是独立的则是用等价类的笛卡尔积是有意义的。如果变量之间在输入定义域中存在逻辑依赖关系则这些依赖关系在笛卡尔积中就会丢失(说抑制可能更确切)。决策表格通过使用“不可能行动”概念来表示条件的不可能组合使我们能够强调这种依赖关系。选择NextDate函数是因为它可以说明输入定义域中的依赖性问题这使得这个例子成为基于决策表测试的一个完美的例子。NextDate的第一次尝试NextDate的第一次尝试先考虑前面为NextDate函数划分的等价类集合。M={月份:每月有天}M={月份:每月有天}M={月份:此月是月}D={日期:日期}D={日期:日期=}D={日期:日期=}D={日期:日期=}Y={年:年是闰年}Y={年:年不是闰年}如果我们希望突出不可能的组合则可以建立具有以下条件和行动的优先条目决策表有规则的第一次尝试有规则的第一次尝试这个决策表会有条规则其中有很多是不可能的NextDate的第二次尝试NextDate的第二次尝试为了说明另一种决策表表示方法这一次采用扩展条目决策表开发并更仔细地研究行动桩。在构建扩展条目决策表时必须保证等价类构成输入定义域的真划分(划分是一组不相交的子集子集的并是全集)如果规则条目之间存在“重叠”则会存在冗余情况使得多个规则都能够满足。为了产生给定日期的NextDate,能够使用的操作只有五种:日期和月份的增和复位年的增我们不允许复位年来回退时间。利用前面的年月日的等价类划分我们可以得到规则的决策表与等价类测试时含个测试用例的笛卡尔积对应。但我们利用不关心条目得到下表条规则的决策表。(仍然有逻辑不可能的规则)第二次尝试的等价类划分第二次尝试的等价类划分M={月份:每月有天}M={月份:每月有天}M={月份:此月是月}D={日期:日期}D={日期:日期=}D={日期:日期=}D={日期:日期=}Y={年:年=}Y={年:年是闰年}Y={年:年时平年}条规则的扩展决策表条规则的扩展决策表如果填满这个决策表的行动条目就会发现月份由一些麻烦的问题。如果是月日,该怎么办每列规则识别一个测试用例规则代表测试用例的输入行动代表程序的主要处理测试用例的输出怎么办根据规格说明和测试用例的输入计算出来第三次尝试的等价类划分第三次尝试的等价类划分通过引入月份等价类的第三个集合可以澄清年末问题M={月份:每月有天}M={月份:每月有天月除外}M={月份:此月是月}M=={月份:此月是月}D={日期:日期}D={日期:日期=}D={日期:日期=}D={日期:日期=}D={日期:日期=}Y={年:年是闰年}Y={年:年不是闰年}这些等价类的笛卡尔积包含个元素。由于组合规则中包含不关心条目最后我们得到一个规则的决策表条规则的决策表条规则的决策表上图所示决策表应该是NextDate函数源代码的基础这个例子从另一方面说明测试如何能够很好地改进程序设计。所有决策表分析都应该在NextDate函数的详细设计期间完成月日月日这四条可以合并NextDate的精简决策表NextDate的精简决策表决策表测试的指导方针决策表测试的指导方针决策表技术适用于具有以下特征的应用程序:Ifthenelse逻辑很突出涉及输入变量子集的计算输入和输出存在复杂因果关系很高的圈(McCabe)复杂度(后面解释)决策表不能很好地伸缩(有n个条件的有限决策表有N个规则与其他技术一样多次尝试的迭代会有所帮助。结构性测试设计结构性测试设计结构性测试(又称为白盒测试)用例设计方常见的主要有以下几种:条件测试基本路径测试循环测试状态机测试设计以实现测试用例对程序的逻辑覆盖和路径覆盖:参见《软件工程-实践者的研究方法》第章页-页测试覆盖种类测试覆盖种类语句覆盖:语句覆盖就是设计若干个测试用例运行被测试程序使得每一条可执行语句至少执行一次判定覆盖(也称为分支覆盖):设计若干个测试用例运行所测程序使程序中每个判断的取真分支和取假分支至少执行一次条件覆盖:设计足够多的测试用例运行所测程序使程序中每个判断的每个条件的每个可能取值至少执行一次判定条件覆盖:设计足够多的测试用例运行所测程序使程序中每个判断的每个条件的所有可能取值至少执行一次并且每个可能的判断结果也至少执行一次条件组合测试:设计足够多的测试用例运行所测程序使程序中每个判断的所有可能的条件取值组合至少执行一次路径测试:设计足够多的测试用例运行所测程序要覆盖程序中所有可能的路径。下面以例子进行分析讲解下面以例子进行分析讲解voidDoWork(intx,inty,intz){intk=,j=if((x>)(z<)){k=x*y语句块j=sqrt(k)}if((x==)||(y>)){j=x*y语句块}j=j语句块}画出前面函数的流程图如右:判断条件语句覆盖:语句覆盖:为了说明简略分别对各个判断的取真、取假分支编号为b、c、d、e。为了测试语句覆盖率只要设计一个测试用例就可以把三个执行语句块中的语句覆盖了。测试用例输入为:{x=、y=、z=}程序执行的路径是:abd该测试用例虽然覆盖了可执行语句但并不能检查判断逻辑是否有问题例如在第一个判断中把错误的写成了||则上面的测试用例仍可以覆盖所有的执行语句。可以说语句覆盖率是最弱的逻辑覆盖准则。分支覆盖分支覆盖对于上面的程序如果设计两个测试用例则可以满足判定覆盖的要求。测试用例的输入为:{x=、y=、z=}程序执行路径是:abd{x=、y=、z=}程序执行路径是:ace上面的两个测试用例虽然能够满足分支覆盖的要求但是也不能对判断条件进行检查例如把第二个条件y>错误的写成y<,、上面的测试用例同样满足了分支覆盖。条件覆盖条件覆盖条件覆盖就是设计若干个测试用例运行被测试对象使得程序中每个判断的每个条件的可能取值至少执行一次。对例子中的所有条件取值加以标记。例如:对于第一个判断:条件x>取真值为T取假值为T条件z<取真值为T取假值为T对于第二个判断:条件x=取真值为T取假值为T条件y>取真值为T取假值为T则可以设计测试用例如下则可以设计测试用例如下上面的测试用例不但覆盖了所有分支的真假两个分支而且覆盖了判断中的所有条件的可能值。但是如果设计了下面的测试用例则虽然满足了条件覆盖但只覆盖了第一个条件的取假分支和第二个条件的取真分支不满足分支覆盖的要求。分支条件覆盖:分支条件覆盖:分支条件覆盖就是设计足够的测试用例使得判断中每个条件的所有可能取值至少执行一次同时每个判断的所有可能判断结果至少执行即要求各个判断的所有可能的条件分支取值组合至少执行一次。根据定义只需设计以下两个测试用例便可以覆盖个条件值以及个判断分支。分支条件覆盖从表面来看它测试了所有条件的取值但是实际上某些条件掩盖了另一些条件。例如对于条件表达式(x>)(z<)来说必须两个条件都满足才能确定表达式为真。如果(x>)为假则一般的编译器不在判断是否z<了。对于第二个表达式(x==)||(y>)来说若x==测试结果为真就认为表达式的结果为真这时不再检查(y>)条件了。因此采用分支条件覆盖逻辑表达式中的错误不一定能够查出来了。条件组合覆盖:条件组合覆盖:条件组合覆盖就是设计足够的测试用例运行被测试对象使得每一个判断的所有可能的条件取值组合至少执行一次。现在对例子中的各个判断的条件取值组合加以标记如下:x>,z<记做TT第一个判断的取真分支x>,z>=记做TT第一个判断的取假分支x<=,z<记做TT第一个判断的取假分支x<=,z>=记做TT第一个判断的取假分支x=,y>记做TT第二个判断的取真分支x=,y<=记做TT第二个判断的取真分支x!=,y>记做TT第二个判断的取真分支x!=,y<=记做TT第二个判断的取假分支根据定义取个测试用例就可以覆盖上面种条件取值的组合。测试用例如下表:上面的测试用例覆盖了所有条件的可能取值的组合覆盖了所有判断的可取分支但是却丢失了一条路径abe。路径测试覆盖路径测试覆盖路径测试覆盖就是设计足够多的测试用例覆盖被测试对象中的所有可能路径。在上面的测试用例中再添加一个测试用例则可对程序进行了全部的路径覆盖。基本路径测试基本路径测试上面的例子是一个很简单的程序函数只有四条路径。但在实践中一个不太复杂的程序其路径都是一个庞大的数字要在测试中覆盖所有的路径是不现实的。为了解决这一难题只得把覆盖的路径数压缩到一定限度内例如程序中的循环体只执行一次。下面介绍的基本路径测试就是这样一种测试方法它在程序控制图的基础上通过分析控制构造的圈复杂度导出基本独立路径集合从而设计测试用例的方法。设计出的测试用例要保证在测试中程序的每一个基本独立路径至少执行一次。在程序控制流图的基础上通过分析控制构造的环路复杂性导出基本可执行路径集合从而设计测试用例。包括以下个步骤和一个工具方法:在程序控制流图的基础上通过分析控制构造的环路复杂性导出基本可执行路径集合从而设计测试用例。包括以下个步骤和一个工具方法:画出程序的控制流图:描述程序控制流的一种图示方法。计算程序圈复杂度:McCabe复杂性度量。从程序的环路复杂性可导出程序基本路径集合中的独立路径最大条数这是确定程序中每个可执行语句至少执行一次所必须的测试用例数目的上界。导出基本独立路径:根据圈复杂度和程序结构设计用例数据输入和预期结果。准备测试用例:确保基本路径集中的每一条路径的执行。先讲一下控制流图的符号在介绍基本路径方法之前必须先介绍一种简单的控制流表示方法即流图。流图使用下面的符号描述逻辑控制流每一种结构化构成元素有一个相应的流图符号。先讲一下控制流图的符号在介绍基本路径方法之前必须先介绍一种简单的控制流表示方法即流图。流图使用下面的符号描述逻辑控制流每一种结构化构成元素有一个相应的流图符号。例子例子如下面的C函数:intSort(intiRecordNum,intiType){intx=inty=while(iRecordNum>){if(==iType){x=ybreak}elseif(==iType)x=yelsex=y}Reutrnx}第一步:画出控制流图第一步:画出控制流图流图中的每一个圆称为流图的结点代表一条或多条语句。流图中的箭头称为边或连接代表控制流。为了说明流图的用法我们采用过程设计表示法此处流程图用来描述程序控制结构。可将流程图映射到一个相应的流图(假设流程图的菱形决定框中不包含复合条件)。在流图中每一个圆称为流图的结点代表一个或多个语句。一个处理方框序列和一个菱形决测框可被映射为一个结点流图中的箭头称为边或连接代表控制流类似于流程图中的箭头。一条边必须终止于一个结点即使该结点并不代表任何语句(例如:参见ifelsethen结构的符号)。由边和结点限定的范围称为区域。计算区域时应包括图外部的范围。任何过程设计都要被翻译成控制流图。画出其程序流程图和对应的控制流图如下:画出其程序流程图和对应的控制流图如下:图(a)流程图图(b)流图第二步:计算圈复杂度第二步:计算圈复杂度圈复杂度是一种为程序逻辑复杂性提供定量测度的软件度量将该度量用于计算程序的基本的独立路径数目为确保所有语句至少执行一次的测试数量的上界。独立路径必须包含一条在定义之前不曾用到的边。有以下三种方法计算圈复杂度:流图中区域的数量对应于环型的复杂性给定流图G的圈复杂度-V(G)定义为V(G)=ENE是流图中边的数量N是流图中结点的数量给定流图G的圈复杂度-V(G)定义为V(G)=PP是流图G中判定结点的数量。对应上面图中的圈复杂度计算如下:流图中有四个区域V(G)=条边结点=V(G)=个判定结点=。第三步:导出基本独立路径第三步:导出基本独立路径根据上面的计算方法可得出四个独立的路径:路径:路径:路径:路径:根据上面的独立路径去设计输入数据使程序分别执行到上面四条路径。第四步:准备测试用例第四步:准备测试用例为了确保基本路径集中的每一条路径的执行根据判断结点给出的条件选择适当的数据以保证某一条路径可以被测试到满足上面例子基本路径集的测试用例是:路径:输入数据:iRecordNum=或者取iRecordNum<的某一个值预期结果:x=路径:输入数据:iRecordNum=,iType=预期结果:x=路径:输入数据:iRecordNum=,iType=预期结果:x=路径:输入数据:iRecordNum=,iType=预期结果:x=这里的预期输出有问题,应该是从程序的规格说明导出,不应该从程序的结构中导出循环测试循环测试循环测试是一种白盒测试技术注重于循环构造的有效性。有四种循环:简单循环串接循环嵌套循环和不规则循环。简单循环:下列测试集用于简单循环其中n是允许通过循环的最大次数。整个跳过循环只有一次通过循环两次通过循环m次通过循环其中m<nnn,n次通过循环。这个和边界值分析是不是很像?嵌套循环:如果将简单循环的测试方法用于嵌套循环可能的测试数就会随嵌套层数成几何级增加这会导致不实际的测试数目下面是一种减少测试数的方法:从最内层循环开始将其它循环设置为最小值对最内层循环使用简单循环而使外层循环的跌代参数(即循环计数)最小并为范围外或排除的值增加其它测试由内向外构造下以个循环的测试但其它的外层循环为最小值并使其它的嵌套循环为“典型”值继续直到测试所有的循环。串接循环:如果串接循环的循环都彼此独立可是使用简单的策略测试。但是如果两个循环串接起来而第一个循环计数是第二个循环的初始值则这两个循环并不是独立的。如果循环不独立则推荐使用的嵌套循环的方法进行测试。不规则循环:不能测试尽量重新设计给结构化的程序结构后再进行测试。状态转换测试设计状态转换测试设计Partofthestatechartofataperecorder状态初始(默认)状态事件动作防护防护转换接受状态(acceptingstate)结果状态(resultantstate)状态机的基本概念事件状态机的基本概念事件信号事件:在状态机范围之外发生的异步事件调用事件:一个对象显式地通知另一个对象改变事件:基于属性改变得事件时间事件:计时器到期或者到达某个绝对时间四类事件两种不同的响应方式系统通过进行转换来对事件作出响应当系统不是处于正确的状态或者进行转换的条件不满足时事件被忽略。状态机的基本概念转换状态机的基本概念转换转换到自身防护将同一状态上同一事件触发的多个转换隔开状态机的基本概念动作和活动状态机的基本概念动作和活动动作:在状态机的某个特殊点执行不可中断地行为该行为被认为不需要花费什么时间(takeanonsignificantamountoftime)。一个动作也可以是作为一个整体不能被中断的一串动作。活动:活动需要花费一些时间因而可以被中断。因此只能在状态中定义活动。“开始到带”是一个动作“到带”是一个活动。状态机的基本概念动作和活动状态机的基本概念动作和活动许多协议和应用模块需要建立TCP链接维护PEER状态机。PEER状态机一般以noinfo状态作为初始状态tcp链接链接后到达TCPCONNECTED状态。那么“建立TCP链接”是一个“动作”还是一个“活动”呢?如果工作于“阻塞”模式TCP建立完成前模块不响应其他事件则“建立TCP链接”是一个动作否则“建立TCP链接”就应该是一个活动二者状态机不同状态机的基本概念嵌套状态状态机的基本概念嵌套状态汽车收音机的状态图其中超状态开启由两个正交区域组成事件触发动作的执行顺序事件触发动作的执行顺序B状态和D状态是A状态的子状态C状态是B状态的子状态。t事件:w、(x,y)、zt事件:p、n、mt事件:p、n、g、st事件:q、s动作是按照一定的顺序来执行的。首先执行的是接受状态的出口标记中定义的动作接下来是指向转换的动作最后是结果状态的入口标记中定义的动作。状态转换测试目的状态转换测试目的许多嵌入式系统或GUI程序全部或部分表现出基于状态的行为。当设计这些系统时可以使用基于状态的建模。从基于状态的模型中可以导出测试用例。基于状态的测试设计技术目标是验证事件、动作、行为与状态转换之间的关系。通过使用这种技术人们就可以判断系统基于状态的行为是否满足系统的规范集合。状态机设计、编码中可能出现缺陷原因分类状态机设计、编码中可能出现缺陷原因分类基于状态的行为出现错误可能有三种原因。第一:状态图无法表示系统功能规范的正确转换。基于状态的测试设计技术不能够揭示这些故障类型因为状态图本身被用作测试的基础。第二:状态图的语法不正确或不一致。可以通过静态分析和评审来发现这些故障(例如通过使用审查清单或工具)如果解决了发现的故障那么就可以使用基于状态的测试设计技术使这个状态图成为动态测试的基础。第三:从状态图到代码的转换。现在已经出现了自动转换的工具如果这个转换过程是自动实现的生成的代码将是状态图的准确的表示那么就没有必要再采用基于状态的测试设计技术。基于状态的测试设计技术适用于手工编码实现状态机的场合。状态图和软件中可能发生的故障:状态状态图和软件中可能发生的故障:状态没有进入转换的状态。(规范和或实现故障)遗漏初始状态。必须定义状态图中的所有路径。当转换到一个没有给出最终子状态的超状态时超状态必须包含一个初始状态。如果没有给出初始状态那么就无法预测转换是在何处终止。(规范和或实现故障)额外状态。系统生成比状态图中多的状态。(实现故障)遗漏状态。系统中没有出现状态图中给出的状态。(实现故障)破坏性状态。转换到无效态而导致系统崩溃。(实现故障)状态图和软件中可能发生的故障:防护状态图和软件中可能发生的故障:防护防护必须指向转换而不是状态。(规范故障)完成事件转换上的防护如果防护被评估为false那么系统会陷入死锁。(规范和或实现故障)初始转换上的防护。初始转换上不能有防护。(规范和或实现故障)重叠防护。在这种情况下无法确定系统将转换到哪种状态。(规范和或实现故障)防护为false但仍然有转换发生系统将达到一个预期之外的最终状态。(实现故障)错误的防护实现。有些条件下这将导致预期之外的系统行为。(实现故障)状态图和软件中可能发生的故障:转换状态图和软件中可能发生的故障:转换转换必须有一个接收状态与一个最终状态。(规范和或实现故障)相互矛盾的转换。一个事件触发系统从一个子状态改变为另一个子状态而同时又触发超状态之外的一个转换这实际上将导致不再能够转换到某个子状态(规范和或实现故障)遗漏或错误转换。最终的状态既不正确也没有被破坏(规范和或实现故障)遗漏或错误动作。执行转换时执行了错误的动作。(规范和或实现故障)状态图和软件中可能发生的故障:事件状态图和软件中可能发生的故障:事件遗漏事件。事件被忽略。(规范和或实现故障)隐含路径。系统对一个定义的事件作出响应但状态图中没有定义这个响应(也被称为“潜路径”)(实现故障)对一个没有定义的事件作出响应(也被称为“后门”)。(实现故障)状态机错误类型的检查单状态机错误类型的检查单状态转换测试技术状态转换测试技术状态转换测试技术(STT)由以下步骤组成编写状态事件表编写转换树编写合法路径测试用例的测试脚本编写非法事件测试用例的测试脚本编写防护测试脚本录音机的状态图录音机的状态图录音机的状态事件表录音机的状态事件表编写录音机的状态转换树编写录音机的状态转换树第一层:初始状态第二层:初始状态经过一次转换可以到达的状态第n层:从第n层经过一次转换可以到达的状态叶子:如果某一层的节点(状态)在以前的某层出现过则这个节点不必再分解下去成为叶子编写合法路径测试用例编写合法路径测试用例借助于转换树与状态事件表可以创建一个只覆盖合法测试路径的测试用例集。转换树上的每一个路径都是一个测试用例这个测试用例覆盖整个路径直到叶子并从叶子返回初始状态(如果可能的话)以便下一个测试用例的执行。也就是说要想测试用例能够连续执行每一个状态都必须有一个回到初始状态的路径。编写合法路径测试用例(续)编写合法路径测试用例(续)编写合法路径测试用例(续)编写合法路径测试用例(续)到达叶子回到初始状态注意:这个测试用例的三个输入在不同时间点按顺序输入输出也是。编写非法事件测试用例编写非法事件测试用例可以从状态事件表中得到非法的状态事件组合。非法的状态事件组合是指当在特定状态时系统没有指定要对该事件做出响应。因而所有非法事件测试用例的预期结果应当是系统对此不作出响应。注意:不应当将非法事件测试用例与系统中明确指出不对某个事件作出实质响应而只是输出一个错误消息的测试用例相混淆。编写非法事件测试脚本(续)编写非法事件测试脚本(续)编写防护测试脚本编写防护测试脚本如果防护由一个带有边界值得条件组成那么需要对该防护进行边界值分析。对每一个防护要从边界值左边和右边两个方向来应用边界条件和测试用例。如果防护由一个复杂的条件组成那么就要使用决策表(见功能性测试设计部分)的方法来覆盖测试。针对防护条件而设计的补充测试用例如下图所示编写防护测试脚本(续)编写防护测试脚本(续)Petri网定义Petri网定义Petri网是一种双向有向图(P,T,In,Out),其中,P和T是不相交的节点集合P我们通常称为地点(places)集合T我们通常称为转移(Transition)集合In和Out是边的集合P={p,p,p,p,p}T={t,t,t}In={<p,t>,<p,t>,<p,t>,<p,t>,<p,t>Out={<t,p>,<t,p>,<t,p>}Petri网例子Petri网例子有标记的Petri网有标记的Petri网定义有标记的Petri网是一种元组(PTInOutM)其中(PTInOut)是个Petri网M是地点到正整数的映射集合M中的元素是个n元组其中n是集合P中的地点个数。对于右图所示的Petri网集合M包含形式为<n,n,n,n,n>,其中ni是与相应地点P有关的整数整数的值表明在这个地点中的令牌(token)的个数右图所示的有标记的Petri网的标记元组M是<,,,,>Petri网的转移Petri网的转移定义转移可以在Petri网中发生如果在其所有输入地点中至少有一个记号定义当触发Petri网一个转移时要从其每个输入地点删除一个令牌(Token),并在每个转移进的地点增加一个令牌(Token)右上图显示了t转移发生后Petri网中令牌的变化转移前转移后事件驱动的Petri网事件驱动的Petri网定义EDPN是一种多向图(PDSInOut)包括三个节点集合PD和S以及两个映射集合In和Out。其中:P是事件地点的集合D是数据地点的集合S是转移的集合In是(PUD)S的有序对偶集合Out是S(PD)的有序对偶集合定义EDPN(PDSInOut)的一个标记M是p元组的一个序列<m,m,……>,其中p=knk和n是集合P和D中的元素个数p元组中的个体项mi表示事件或数据地点中的记号个数每个标记M对应Petri网络的一个执行EDPN的例子EDPN的例子事件地点数据地点将状态机转换成EPDN将状态机转换成EPDN将状态机中的状态当做“数据地点”将状态机中的转换当做“转移”将状态机中的转换上的输入事件作为“输入事件地点”用正三角形表示将转换上的动作作为“输出事件地点”用倒三角形表示。Petri网中边的方向规定如下:边从表示“接受状态”的“数据地点”和“输入事件”的“事件地点”出发结束于“转移”。边从表示“转移”出发结束于表示“结果状态”的数据地点和“输出事件”的事件地点EDPN的执行过程EDPN的执行过程例子:土星牌挡风玻璃雨刷例子:土星牌挡风玻璃雨刷某些土星牌汽车的挡风玻璃雨刷是由带刻度的控制杆控制的。这种控制杆有四个位置:停止间歇低速和高速刻度盘位置有三个位置分别是数字和。刻度盘指示三种间歇速度刻度盘的位置只有当控制杆在间歇位置上时才有意义。下图的决策表给出了挡风雨刷对应控制杆和刻度盘的工作速度土星牌挡风玻璃雨刷的输入和输出事件土星牌挡风玻璃雨刷的输入和输出事件土星牌挡风玻璃雨刷的状态和转移土星牌挡风玻璃雨刷的状态和转移控制杆的状态机和EDPN控制杆的状态机和EDPN刻度盘的状态机和EDPN刻度盘的状态机和EDPN档风玻璃雨刷系统的EDPN档风玻璃雨刷系统的EDPN档风玻璃雨刷系统的EDPN的样本场景档风玻璃雨刷系统的EDPN的样本场景样本场景中的并行行为样本场景中的并行行为如何使用EPDN来进行测试设计如何使用EPDN来进行测试设计EPDN是一张有向图,就如同状态机和程序流图一样所以EPDN对测试设计的意义就在于对图的覆盖上(节点或边)。可以将EPDN转换成状态机,采用状态转换测试设计的方法,遍历所有可能的状态转换可以采用类似基路径测试的方法遍历Petri网中所有的节点面向对象的单元测试设计面向对象的单元测试设计对OO软件的类测试相当于传统软件的单元测试。和传统软件的单元测试不同他往往关注模块的算法细节和模块接口间流动的数据OO软件的类测试是由封装在类中的操作和类的状态行为所驱动的。OO软件测试的特点:因为属性和操作是被封装的对类之外操作的测试通常是徒劳的。封装使对对象的状态快照难于获得。继承也给测试带来了难度即使是彻底复用的对每个新的使用语境也需要重新测试。多重继承更增加了需要测试的语境的数量使测试进一步复杂化。如果从超类导出的测试用例被用于相同的问题域有可能对超类导出的测试用例集可以用于子类的测试然而如果子类被用于完全不同的语境则超类的测试用例将没有多大用途必须设计新的测试用例集。面向对象的单元测试设计面向对象的单元测试设计类测试一般有两种主要的方式:功能性测试和结构性测试即对应于传统结构化软件的黑盒测试和白盒测试。功能性测试以类的规格说明为基础它主要检查类是否符合其规格说明的要求。例如对于Stack类即检查它的操作是否满足LIFO规则结构性测试则从程序出发它需要考虑其中的代码是否正确同样是Stack类就要检查其中代码是否动作正确且至少执行过一次。面向对象的单元白盒测试策略面向对象的单元白盒测试策略结构性测试对类中的方法进行测试它把类作为一个单元来进行测试。测试分为两层:第一层考虑类中各独立方法的代码即方法的单独测试第二层考虑方法之间的相互作用即方法之间的综合测试。。每个方法的测试要求能针对其所有的输入情况但这样还不够只有对这些方法之间的接口也做同样测试才能认为测试是完整的。对于一个类的测试要保证类在其状态的代表集上能够正确工作构造函数的参数选择以及消息序列的选择都要满足这一准则。因此在这两个不同的测试层次上应分别做到:面向对象的单元白盒测试策略面向对象的单元白盒测试策略方法的单独测试:结构性测试的第一层是考虑各独立的方法这可以与过程的测试采用同样的方法两者之间最大的差别在于方法改变了它所在实例的状态这就要取得隐藏的状态信息来估算测试的结果传给其它对象的消息被忽略而以桩来代替并根据所传的消息返回相应的值测试数据要求能完全覆盖类中代码可以用传统的测试技术来获取。方法的综合测试:第二层要考虑一个方法调用本对象类中的其它方法和从一个类向其它类发送信息的情况。单独测试一个方法时只考虑其本身执行的情况。而没有考虑动作的顺序问题测试用例中加入了激发这些调用的信息以检查它们是否正确运行了。对于同一类中方法之间的调用一般只需要极少甚至不用附加数据因为方法都是对类进行存取故这一类测试的准则是要求遍历类的所有主要状态。类方法的综合测试用例设计随机测试类方法的综合测试用例设计随机测试为了提供随机测试方法的简略性举例考虑一个银行应用其中account类有下列操作:opensetupdepositwithdrawbalancesummarizecreditLimit和closeP这些操作的每一个均可应用于account但是问题的性质隐含了一些限制(例如帐号必须在其他操作可应用前被打开在所有操作完成后被关闭)。即使有了这些限制还是存在操作的很多排列。一个account实例的最小的行为生命历史包括下面操作:open•Setup•deposit•withdraw•close这表示了account的最小测试序列然而大量的其他行为可能在下面序列中发生:open•setup•deposit•deposit|withdraw|balance|summarize|creditiLimitn•withdraw•close一系列不同的操作序列可以随机产生例如:测试用例r:open•setup•deposit•deposit•balance•summarize•withdraw•close测试用例r:open•setup•deposit•withdraw•deposit•balance•creditLimit•withdraw•close这些和其他的随机顺序测试被进行以测试不同的类实例生命历史。随机测试的可能排列的数量可能增长非常大。可以使用类划分测试来改善测试效果。类方法的综合测试用例设计划分测试类方法的综合测试用例设计划分测试测试划分(parititiontesting)可以减少测试类所需的测试用例的数量采用的是基本于传统软件的等价划分P类似的方式:输入和输出被分类并且测试用例被设计以处理每个类别。类的等价划分测试有如下几种:基于状态的划分基于类的操作改变类状态的能力来对类操作分类再次考虑account类状态操作包括deposit和withdraw而非状态操作包括balance、summarize和creditLimit。测试被以这样一种分别独立测试改变状态的操作和那些不改变状态的操作的方式来设计因此测试用例p:open•setup•deposit•deposit•withdraw•withdraw•close测试用例p:open•setup•deposit•summarize•creditLimit•withdraw•close测试用例p改变状态而测试用例p测试不改变状态的操作(除了那些在最小测试序列中的操作)。基于属性的划分基于它们使用的属性来对类操作分类对accout类属性balance和creditLimit可被用于定义划分操作被分为三个类别:()使用creditLimit的操作()修改creditLimit的操作()不使用和修改creditLimitde操作。然后对每个划分设计测试序列。基于类别的划分基于各自完成的类属函数来对类操作分类例如在accout类中的操作可被分类为初始化操作(open、setup)、计算操作(deposit、withdraw)、查询操作(balance、summarize、creditLimit)和终止操作(close)。类方法综合测试用例设计类状态测试类方法综合测试用例设计类状态测试状态-转换图(STD)是作为表示类的动态行为的模型P。类的STD可被用于帮助导出测试类(和那些与其协作的类)的动态行为的测试序列。右图给出了前面讨论的account类的STD。根据该图初始变迁经过了emptyacct和setupacct状态类的实例的大多数行为发生在workingacct状态最终的withdrawal和close使得account类分别向nonworkingacct和deadacct状态发生变迁。设计的测试用例集应该使类的所有可能状态达到完全的覆盖P即应用于测试的操作序列应该导致accout类的变迁穿越所有允许的状态测试用例s:open•setupAccnt•deposit(initial)•withdraw(final)•close应该注意该序列等同于小节讨论的最小测试序列加入其他测试序列得到最小序列中:测试用例s:open•setupAccnt•deposit(initial)•deposot•balance•credit•withdraw(final)•close测试用例s:open•setupAccnt•deposit(initial)•deposit•withdraw•accntInfo•withdraw(final)•clos

用户评论(0)

0/200

精彩专题

上传我的资料

每篇奖励 +2积分

资料评价:

/123
0下载券 下载 加入VIP, 送下载券

意见
反馈

立即扫码关注

爱问共享资料微信公众号

返回
顶部