面向对象的软件测试技术概述_第1页
面向对象的软件测试技术概述_第2页
面向对象的软件测试技术概述_第3页
面向对象的软件测试技术概述_第4页
面向对象的软件测试技术概述_第5页
已阅读5页,还剩118页未读 继续免费阅读

下载本文档

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

文档简介

1、技术创新,变革未来面向对象的软件测试技术概述目录1 面向对象的基本概念2 面向对象的软件测试与传统软件测试3 面向对象软件测试模型4 面向对象的单元测试5 面向对象的集成测试6 面向对象的系统测试7 GUI测试面向对象软件具有更严重的潜在的测试问题:由于面向对象技术开发的软件代码重用率高,更需要严格测试,避免错误的繁衍。 序 面向对象技术是一种全新的软件开发技术,正逐渐代替被广泛使用的面向过程开发方法,被看成是解决软件危机的新兴技术。面向对象的特征是封装、继承、多态;面向对象设计的目的是达到最大限度的重用;面向对象技术产生更好的系统结构,更规范的编程风格,极大的优化了数据使用的安全性;6.1

2、面向对象的基本概念对象类消息接口封装继承多态面向对象思想的由来“对象”一词在现实生活中经常会遇到,它表示现实世界中的某个具体的事物。随着计算机的普及应用,人们越来越希望能更直接与计算机进行交互,而不需要经过专门学习和长时间训练后才能使用它。这一强烈愿望使软件设计人员的负担越来越重,也为计算机领域自身的发展提出了新的要求。传统的程序设计思想无法满足这一要求,人们就开始寻求一种更能反映人类解决问题的自然方法,面向对象技术就是在这样的情况下产生的。面向对象与结构化开发方法现实世界为对象世界OOAOODOOP结构化分析结构化设计结构化编程顺序存储指令计算机过程世界面向对象开发方法结构化开发方法OOA/

3、OOD/OOP是一种从概念上更为直接的路径。面向过程的结构化方法存在着与现实世界之间的巨大差距。面向对象的基本概念Peter Coad 和 Edward Yourdon 提出下列等式认识面向对象方法: 面向对象 对象(Object) 分类(Classification) 继承(Inheritance) 通过消息的通信 (Communication with message)采用这四个概念开发的软件系统是面向对象的。面向对象技术面向对象方法的出现,实际上是程序设计方法发展的-个返朴归真过程。面向对象的实质:从系统的组成上来进行分解。对问题自然分割,利用类及对象作为基本构造单元,以更接近人类思维的

4、方式建立问题域模型,从而使设计出的软件尽可能直接地描述现实世界,构造出模块化的、可重用的、可维护性好的软件,并能控制软件的复杂性降低开发维护费用。对象对象是指包含了一组属性以及对这些属性的操作的封装体。对象之间存在着一定的关系,对象之间的交互与合作构成更高级的行为。王五由他的头、胳膊、腿和身体组成汽车是一种交通工具对象间的由分解所构成的关系,part of层次;具有代表一种一般特性的对象之间的聚合关系,is a层次;代表更一般的对象间在物理上或概念上有关的相关关系。人乘坐或驾驶汽车对象是软件开发期间测试的直接目标。面向对象软件测试所关注的焦点: (1)对象的行为是否符合它的规定说明; (2)该

5、对象与和它相关的对象是否协同工作。类类是具有相同属性和相同行为的对象的集合。面向对象程序运行的基本元素是对象,而类则是用来定义对象这一基本元素的。在面向对象程序设计中,类是一个独立的程序单位,它有一个类名,还包括用于描述对象属性的成员变量和用于描述对象行为的成员函数。类是对象的抽象定义。使用类时必须先实例化用对象名创建类的实例,再通过这个对象去访问类的成员变量,去调用类的成员函数。类和对象之间关系类似于程序设计语言中类型和变量之间的关系。消息消息是对象的操作将要执行的一种请求,也被称为成员函数调用或者方法调用。面向对象的程序的执行实际上是执行一个由消息连接起来的方法序列。 “发送消息M到对象N

6、” =“调用N对象的M方法” 消息传递是对象间通信息的手段。一个消息通常包括接收对象名、调用的操作名和适当参数(如有必要)。消息只告诉接收对象需要完成什么操作,但并不指示接收者怎样去完成操作。消息完全由接收者解释,接收者独立决定采用什么方法来完成所需操作。消息(续)从测试的角度看,关于消息有下面的结论:(1)消息的发送者决定何时进行发送消息,可能会做出错误的决定;(2)消息的接收者可能收到非预期的特定消息,并做出不正确地反映;(3)消息可能含有参数。在处理一条消息时,参数能被接收者使用或修改。若传递的参数是对象,那么在消息被处理前和处理后,对象必须处于正确的状态,而且必须是接收者所期望的接口。

7、 接口接口是行为声明的集合。接口是由一些规范构成的,规范定义了类的一套完整的公共行为。是一种非常有效的编程工具,可以在不破坏现有应用程序情况下使对象得以发展。从测试的角度,关于接口有下面的结论:(1)接口封装了操作的说明。如果这一接口包含的行为和类的行为不相符,那么这一接口的说明就有问题。(2)接口非孤立,它与其它的接口和类有一定的关系。封装封装:是一种信息隐蔽技术,用户只能看到对象封装界面上的信息,对象内部的实现对用户是隐蔽的。防止外界未被授权地访问一些信息和功能。封装的目的使对象的使用者和设计者产生分离使对象的定义和实现分开例:档风玻璃雨刷系统某些档风玻璃雨刷是由带刻度盘的控制杆控制的。控

8、制杆有4个位置:停止、间歇、低速、高速;刻度盘有3个位置:1、2、3。刻度盘位置指示三种间歇速度,刻度盘的位置只有当控制杆在间歇位置上时才有意义。以下决策表给出了挡风玻璃雨刷对应控制杆和刻度盘的工作速度:C1控制杆C2刻度盘停止间歇1间歇2间歇3低速高速A1雨刷046123060关间歇低速高速123每分钟0次摆动每分钟4次摆动每分钟6次摆动每分钟12次摆动每分钟30次摆动每分钟60次摆动档风玻璃雨刷类的行为控制杆雨刷刻度盘 定义(类):控制杆CLASS lever(lever position; private senseLeverUp(), Private senseLeverDown()刻

9、度盘CLASS dial(dial position; private senseDialUp(), private senseDialDown)雨刷器CLASS wiper(wiperSpeed; setWiperSpeed(new Speed)控制杆和刻度盘永远报告各自的位置,雨刷类成为“主程序”。类之间的耦合很小的封装最大限度提高重用的潜力,使合成和测试更容易。继承继承继承是类间的基本关系,是基于层次关系的不同类共享数据和操作的一种机制。继承允许一个新的类在一个已有的类的基础上进行定义。一个父类可以有多个子类,这些子类都是父类的特例。父类描述了这些子类的公共属性和操作,子类中还可以定义它

10、自己的属性和操作。单一继承:一个子类只有唯一的一个父类多重继承:一个子类有一个以上的父类从测试的角度来看,继承包含以下内容:(1)继承提供一种机制,通过这种机制,潜在的错误能够从一个类传递到它的派生类。(2)子类是从父类继承过来的,子类也就继承了父类的属性和操作。因此,可以用测试父类的方法对子类进行测试。继承使类作为单元测试的选择变得复杂;使用“扁平类” 的单元测试可解决继承的问题,即一个类经过扩充包括全部所继承的属性和操作的原始类的类。例,SATM系统部分的UML继承图accountaccountNumberbalanceGetbalance()Setbalance()checkingAcc

11、ountcheckProcessingChargecheckNumberpostCharge()savingsAccountinterestRatepostInterest()checkingAccountaccountNumberbalancecheckProcessingChargecheckNumberGetbalance()Setbalance()postCharge()savingsAccountaccountNumberbalanceinterestRateGetbalance()Setbalance()postInterest()类继承扁平化处理类多态多态是指同一个操作作用于不同

12、的对象可以有不同的解释,产生不同的执行结果。是面向对象程序设计语言的基本机制,是将一个方法名与不同方法关联的能力。消息的发送者不需要知道接收对象的类;接收对象可以属于任意的类。多态性是一个非常重要的特征。支持灵活的设计,同时易于维护。6.2 面向对象与传统软件的测试面向对象技术所独有的封装、继承、多态等新特点给测试带来一系列新的问题,增加了测试的难度。与传统的面向过程的程序设计相比,面向对象程序设计产生错误的可能性增大,或者使得传统软件测试中的重点不再那么突出,使原来测试经验和实践证明的次要方面成为了主要问题。例如:函数 y = Function(x) 如果该函数写在传统的面向过程的程序中,通

13、常考虑的是函数Function()本身的行为特点。但若写在面向对象的程序中,就不得不同时考虑基类函数Base:Function() 的行为和派生类函数Derived:Function()的行为。面向对象技术的特点给测试带来的新问题具体表现为:(1)封装把数据及对数据的操作封装在一起,限制了对象属性对外的透明性和外界对它的操作权限,在某种程度上避免了对数据的非法操作,有效防止了故障的扩散。但同时,封装机制也给测试数据的生成、测试路径的选取以及测试结构的分析带来了困难。(2)继承实现了共享父类中定义的数据和操作,同时也可定义新的特征。子类是在新的环境中存在,所以父类的正确性不能保证子类的正确性。继

14、承使代码的重用率得到了提高,但同时也使故障的传播几率增加。(3)多态和动态绑定增加了系统运行中可能的执行路径,而且给面向对象软件带来了严重的不确定性,给测试覆盖率的活动带来新的困难。 面向对象与传统软件的测试(续)与传统软件相比,由于存在的诸如继承、多态、动态绑定等关系,面向对象软件具有更复杂的依赖关系,一个类将不可避免的依赖于其它的类,从而增加了面向对象软件测试的难度。传统软件中存在的依赖关系有:变量间的数据依赖;模块间的调用依赖;变量与其类型间的定义依赖;模块与其变量间的功能依赖。面向对象软件除了存在上述依赖关系外,还存在以下的依赖关系:类与类间的依赖;类与操作间的依赖;类与消息间的依赖;

15、类与变量间的依赖;操作与变量间的依赖;操作与消息间的依赖;操作与操作间的依赖。面向对象与传统软件的测试(续)6.3 面向对象软件测试模型面向对象的程序结构不再是传统的功能模块结构,作为一个整体,原有集成测试所要求的逐步将开发的模块搭建在一起进行测试的方法已变得不可行。而且,面向对象软件抛弃了传统的开发模式,已经不可能用功能细化的观点来检测面向对象分析和设计的结果。因此,传统的测试模型对面向对象软件已经不再适用。面向对象的软件开发模型将开发过程定义为面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)三个阶段。针对这种开发模型,应该建立一种新的测试模型。面向对象软件测试模型(续

16、)面向对象的测试模型OO System TestOO Integrate TestOOAOODOOPOOA TestOOD TestOOP TestOO Unit Test面向对象 分析的测试面向对象 设计的测试面向对象 编程的测试面向对象系统测试面向对象单元测试面向对象集成测试面向对象软件测试模型(续)OOA Test 和OOD Test 是对分析结果和设计结果的测试,主要是对分析设计产生的文档进行测试,是软件开发前期的关键性测试。OOP Test 主要针对编程风格和程序代码实现进行测试,主要的测试内容在面向对象单元测试和面向对象集成测试中体现。面向对象单元测试针对程序内部具体单一功能的模块

17、进行测试,比如在C+程序中主要就是对类成员函数的测试。面向对象集成测试主要对系统内部的相互服务进行测试,如成员函数间的相互作用、类间的消息传递等。面向对象系统测试是基于面向对象集成测试的最后阶段的测试,主要以用户需求为测试标准。面向对象分析的测试(OOA Test)OOA的测试重点在其完整性和冗余性。对OOA阶段的测试划分为五个方面:对认定的对象的测试;对认定的结构的测试;对认定的主题的测试;对定义的属性和实例关联的测试;对定义的服务和消息关联的测试。 OOA中认定的对象:是指对问题空间中的结构、其他系统、设备、被记忆的事件、系统涉及的人员等实际实例的抽象。面向对象设计的测试(OOD Test

18、)OOD是OOA的进一步细化和扩充,重点在于说明项目的实施方案,来确定类和类的结构。对OOD的测试,应针对功能的实现和重用以及对OOA结果的拓展进行,从以下三方面考虑:(1)对认定的类的测试是否涵盖了OOA中所有认定的对象;是否能体现OOA中定义的属性;是否能实现OOA中定义的服务;是否对应着一个含义明确的数据抽象;是否尽可能少的依赖其他类;类中的方法是否单用途。(2)对构造的类层次结构的测试类层次结构是否涵盖了所有定义的类;是否能体现OOA中定义的实例关联;是否能实现OOA中定义的消息关联;子类是否具有父类没有的新特性;子类间的共同特性是否完全在父类中得以体现。(3)对类库支持的测试面向对象

19、编程的测试(OOP Test)面向对象程序是把功能的实现分布在类中。能正确实现功能的类,通过消息传递来协同实现设计要求的功能。这种程序架构能将出现的错误精确的确定在某一具体的类。 对OOP的测试重点集中在类功能的实现和相应的面向对象程序架构,主要体现为以下两个方面:(1)数据成员是否满足数据封装的要求基本原则是数据成员是否被外界直接调用。(2)类是否实现了要求的功能测试类的功能,不能仅满足于代码能无错运行或被测试的类能提供的功能正确,应以所做的OOD结果为依据,检测类提供的功能是否满足了设计的要求,是否有缺陷。 取决于单元的构成;四层:以单个操作或方法为单元:操作/方法测试:单元测试;类测试:

20、类内的测试;集成测试:类间测试;系统测试:端口事件层上测试;三层:以类为单元面向对象测试层次datedaymonthyear类聚合例1:NextDate面向对象的实现testItDateDay dMonth mYear yDate(pDay,pMonth,pYear)Increment()printDate()CalendarUnit abstract classcurrentPos As IntegerCalendarUnit(pCurrentPos)setCurrentPos(pCurrentPos)Increment() booleanDayMonth mDay(pDay,Month,p

21、Month)setCurrentPos(pCurrentPos)getDay()Increment()YearYear(int pYear)setCurrentPos(pCurrentPos)getYear()Incrment()isLeap() booleanMonthprivate Year yprivate sizeIndex=Month(pcur,Year pYear)setCurrentPos(pCurrentPos)setMonth(pcur,Year pYear)getMonth()getMonthSize()Increment()O-oCalendar 中的类例2:货币转换应用

22、程序美圆金额等价于巴西加拿大欧共体日本计算清除退出货币转换程序是事件驱动的程序,强调与GUI关联的代码。将美元转换为任意四种货币,货币选择由单选按钮控制,相互排斥。计算按钮将美元金额转换为所选货币的等量金额清除按钮重新设置货币选择、美元金额、等量货币金额、相关标签。退出按钮结束该应用程序。输入事件输出事件ip1ip2ip2.1ip2.2ip2.3ip2.4ip3ip4ip5ip6输入美元金额按下国家按钮按下巴西按下加拿大按下欧共体按下日本按下计算按钮按下清除按钮按下退出按钮在错误消息中按下OKop1op2op2.5op3op4op5op6op7op8op9op10显示美元金额显示货币名称显示省

23、略号指示所选国家重新设置所选国家显示外币值错误消息:必须选择国家错误消息:必须输入美元金额错误消息:必须选择国家输入美元金额重新设置美元金额重新设置等价货币金额货币转换程序的输入和输出事件Ip3/op8Ip6空闲遗漏国家和美圆消息国家已选择遗漏美圆信息两种输入已完成美圆金额已输入遗漏国家消息已显示等价金额Ip4 or ip5Ip2/op2,op3Ip3/op7Ip6Ip4 or ip 5 Op2.5,op4 op9,and op 10Ip1/op1Ip3/op5Ip2/op2,op3Ip1/op1Ip6Ip3/op6图16-7 高层有限状态机没有显示在每个状态会发生的所有事件,按下清除和退出按

24、钮,可以在任何状态中发生。空闲巴西欧共体加拿大日本Ip2.1Op2.1Op3.1Ip2.2Op2.2Op3.2Ip2.3Op2.3Op3.3Op4.1Ip2.4Op2.4Op3.4Ip2.3Op2.3Op3.3Ip2.1Op2.1Op3.1Op4.3Ip2.2Op2.2Op3.2Op4.1Ip2.1Op2.1Op3.1Op4.2Ip2.3Op2.3Op3.3Op4.4Ip2.4Op2.4Op3.4Op4.3Ip2.4Op2.4Op3.4Op4.2Ip2.2Op2.2Op3.2Op4.4图16-8 选择国家状态详细视图在存储器中空闲遗漏国家和美圆消息国家已选择遗漏美圆信息两种输入已完成美圆金额已

25、输入遗漏国家消息已显示等价金额Ip4Ip2/op2,op3Ip3/op8Ip6Ip3/op7Ip6Ip1/op1Ip2/op2,op3Ip3/op5Ip1/op1Ip3/op6Ip6Ip2/op2,op3Ip1/op1Ip5结束货币转换应用程序状态图执行退出清除状态转移图的面向对象软件测试面向对象设计方法通常采用状态转移图建立对象的动态行为模型。状态转移图用于刻画对象响应各种事件时状态发生转移的情况,图中结点表示对象的某个可能状态,结点之间的有向边通常用“事件/动作”标出。基于状态的测试是通过检查对象的状态在执行某个方法后是否会转移到预期状态的一种测试技术。使用该技术能够检验类中的方法是否能正

26、确地交互。 因为对象的状态是通过对象数据成员的值反映出来,所以检查对象的状态实际上就是跟踪监视对象数据成员的值的变化。如果某个方法执行后对象的状态未能按预期的方式改变,则说明该方法含有错误。6.4 面向对象的单元测试面向对象测试的单元定义可以编译执行的最小软件组件;(和传统测试一样,但放弃了封装的特点)由一个设计人员开发的软件组件;只包含单一操作或方法的类或子类。(设计用例方便,使集成测试目标清晰)以方法为单元还是以类为单元,根据具体环境确定最适合的方法。“操作”是指类函数定义,“方法”指其实现。面向对象的单元测试-以方法为单元传统的单元测试是针对程序的函数、过程或完成某一特定功能的程序块。单

27、独的看待类的成员函数,与面向过程程序中的函数或过程没有本质的区别,传统的测试方法在面向对象单元测试中都可使用,如等价类划分法、因果图法、边值分析法、逻辑覆盖法、路径分析法等等。面向对象编程的特性使得对成员函数的测试又不完全等同于传统的函数或过程测试。不再孤立地测试单个操作,而是将操作作为类的一部分。尤其是继承特性和多态特性,使子类继承或重载的父类成员函数出现了传统测试中未遇见的问题。考虑如下两个问题:(1)继承的成员函数是否都不需要测试?(2)对父类的测试是否能照搬到子类?面向对象的单元测试(续)继承的成员函数是否都不需要测试? 对父类中已经测试过的成员函数,以下两种情况需要在子类中重新测试:

28、 a)继承的成员函数在子类中做了改动; b)成员函数调用了改动过的成员函数的部分。例:假设存在父类Base有Inherited()和Redefined()这两个成员函数,继承父类Base的子类Derived只对Redefined() 做了改动。那么,Derived:Redefined()就需要重新测试;对于Derived:Inherited(),若它包含了调用Redefined()的语句 (比如:x=x/Redefined()),就需要重新测试,否则就不需要。面向对象的单元测试(续)对父类的测试是否能照搬到子类? 引用前面的假设,成员函数Base:Redefined()和Derived:Red

29、efined()已经是不同的。那么,按理应该要对Derived:Redefined()重新测试分析,设计测试用例。但是由于面向对象的继承使得两个函数相似,故只需要在对Base:Redefined()的测试要求和测试用例上添加对Derived:Redefined()新的测试要求和增补相应测试用例。例 Base:Redefined()含有如下语句: If (value0) message(“less”); else if (value=0) message(“equal”); else message(“more”); 面向对象的单元测试(续)例(续) 在Derived:Redefined()中定

30、义为: If (value0) message(“less”); else if (value=0) message(“It is equal”); else message(“more”); if (value=88) message(“luck”); 在原有对父类Base的测试上,对Derived:Redefined()的测试只需作如下改动:将value=0的测试结果期望改动;增加value=88的测试。 设计测试用例需要能够实例化的“桩”类和起驱动器作用的“主程序”类;方法一般比较简单,复杂度较低;创建桩工作量较大;测试工作主要集中在集成测试:类内和类间; 例:o-oCalendar的伪

31、代码:CalendarUnit类:两个操作(设置取值和标志)Testlt类(测试驱动器)Date类(获取日期,计算下一日期并打印日期)Day类(设置/获取日期)Month 类(设置/获取月份及天数)Year类(设置/获取年份及闰年判别)Testlt类和Date类123testIt4567Date.constructor891011121314151617181920Date.incrementDate.printDateDay类212223Day.constructorabDay.setCurrentPos232425Day.setDay2627Day.getDay282930313233Da

32、y.increment394041Month.constructorabMonth.setCurrentPos363738Month.setMonth3940Month.getMonth474849505152Month.increment414246434445Month.getMonthSizeMonth类的程序图类:CalendarUnit class CalendarUnit abstract class currentPos As Integer CalendarUnit(pCurrnetPos) currentPos = pCurrnetPos End CalendarUnita.

33、 setCurrentPos(pCurrnetPos)b. currentPos = pCurrnetPos End setCurrentPos abstract protected boolean increment()类:testlt class testlt main()1. Date testdate(testMonth,testDay,testYear)2. testdate.increment()3. testdate.printDate() End testlt类:Date class Date private Day d private Month m private Year

34、 y4. Date(pMonth,pDay,pYear)5. Year y(pYear)6. Month m(pMonth,y)7. Day d(pDay,m) End Date constructor19.printDate()20. Output(m.getMonth()+”/”+d.getDay()+”/”+y.getYear() End printDate8. increment()9. if (NOT(d.increment()10.Then11. if(NOT(m.increment()12. Then13. y.increment()14. m.setMonth(1,y) d.s

35、etDay(1,m)15. Else16. d.setDay(1,m)17. Endif18.Endif End increment类:Day class Day is A CalendarUnit private Month m21. Day(pDay,Month pMonth)22. setDay(pDay,pMonth) End Day constructor23. setDay(pDay, pMonth)24. setCurrentPos(pDay)25. m = pMonth End setDay26. getDay()27. return currentPos End getDay

36、28. boolean increment()29. currentPos = currentPos+130. if(currentPos=m.getMonthSize()31. Then return true32. Else return false33. Endif End increment类:Month class Month is A CalendarUnit private Year y private sizeIndex=34.Month(pcur,Year pYear)35. setMonth(pcur,Year pYear) End Month constructor36.

37、setMonth(pcur,Year pYear)37. setCurrentPos(pcur)38. y=pYear End setMonth39.getMonth()40. return currentPos End getMonth41.getMonthSize()42. if(y.isleap()43. Then sizeIndex1=2944. Else sizeIndex1=2845. Endif46. return sizeIndexcurrentPos-1 End getMonthSize47.boolean increment()48. currentPos=currentP

38、os+149. if(currentPos12)50. Then return fasle51. Else return true52. Endif End increment类:Year class Year is A CalendarUnit53. Year(pYear)54. setCurrentPos(pYear) End Year constructor55. getYear()56. return currentPos End getYear57. boolean increment()58. currentPos = currentPos+159. return true End

39、 increment60. boolean isleap()61. if(currentPos MOD 4=0)AND NOT(currentPos MOD 100=0)OR(currentPos MOD 400=0)62. Then return true63. Else return false64. Endif End isleapDate.increment的单元测试三个等价类:D1=日期:1=日期月的最后日期D2=日期:日期是非12月的最后日期D3=日期:日期是12月31日 可以解决类内集成问题;主要问题是类的继承性、抽象类等问题;静态视图继承被忽略,扁平化的类可以解决;不能测试抽象

40、类;以类为单元在没有类的继承性,只有内部的复杂性时最有意义面向对象的单元测试-以类为单元类的功能性和结构性测试对面向对象软件的类测试相当于传统软件中的单元测试。 类的测试用例可以先根据其中的方法设计,然后扩展到方法之间的调用关系。类测试一般也采用传统的两种测试方式:功能性测试和结构性测试,即黑盒测试和白盒测试。功能性测试以类的规格说明为基础,主要检查类是否符合其规格说明的要求。功能性测试包括两个层次:类的规格说明和方法的规格说明。结构性测试则是从程序出发,对类中方法进行测试,需要考虑其中的代码是否正确。测试分为两层:第一层考虑类中各独立方法的代码,即方法要做单独测试;第二层考虑方法之间的相互作

41、用,即方法需要进行综合测试。例:挡风玻璃雨刷(三个类合并为一个类)class windshieldWiper private wiperSpeed;leverPosition;dialPosition windshieldWiper(wiperSpeed,leverPosition,dialPosition) getWiperSpeed() setWiperSpeed() getLeverPosition() setLeverPosition() getDialPosition() setDialPosition() senseLeverUp() senseLeverDown() senseD

42、ialUp() senseDialDown()End class windshieldWiper断电加电关间歇低速高速123046123060leverdownleverupleverdownleverdownleverupleverupdialDowndialDowndialUpdialUpInstate(Int)Instate(off)Instate(1)Instate(2)Instate(3)Instate(low)Instate(High)Instate(Int)Instate(low)Instate(1)Instate(2)windshieldWiper类的状态图senseLever

43、Up() Case leverPosition Of Case 1:Off leverPosition=Int Case dialPosition Of Case 1:1 wiperSpeed=4 Case 2:2 wiperSpeed=6 Case 3:3 wiperSpeed=12 EndCase dialPosition Case 2:Int leverPosition=Low wiperSpeed=30 Case 3:Low leverPosition=High wiperSpeed=60 Case 4:High (impossible;error condition) EndCase

44、 leverPosition windshieldWiper类的单元测试采用由下往上的测试;senseLeverUp/ senseLeverDown/DialUp/DialDown的测试测试windshieldWiper类的其他部分测试驱动器类的伪代码:class testSenseLeverUp wiperSpeed leverPos dialPos testResult booleanmain() windshieldWiper testCase(0,Off,1) testCase.senseLeverUp() leverPos= testCase.getLeverPosition() i

45、f leverPos=Int Then testResult=Pass Else testResult=Fail EndifEnd mainclass testWindshieldWiper wiperSpeed leverPos dialPos testResult booleanmain() windshieldWiper testCase(0,Off,1) testCase.senseLeverUp() wiperSpeed = testCase.getWiperSpeed() if wiperSpeed=4 Then testResult=Pass Else testResult=Fa

46、il EndifEnd main基于类行为图定义测试覆盖指标:每个事件的覆盖组件中每个状态的覆盖;组件中每个转移的覆盖;所有交互状态覆盖;客户定义用例场景;测试用例前提windshieldWiper事件(方法)预期leverPos的输出值123456windshieldWiper(0,Off,1)windshieldWiper(0,Int,1) windshieldWiper(0,Low,1)windshieldWiper(0,High,1)windshieldWiper(0,Low,1)windshieldWiper(0,Int,1)senseLeverUp()senseLeverUp()s

47、enseLeverUp()senseLeverDown()senseLeverDown()senseLeverDown()“间歇”“低速”“高速”“低速”“间歇”“关”控制杆组件每个状态/转移覆盖层次的测试用例:场景覆盖准则与系统级测试几乎相同,场景:UC1正常用法描述前提挡风玻璃雨刷在“关”位置,“刻度盘”在位置1;用户将控制杆推到“间歇”,然后将刻度盘从位置2转到位置3;然后将控制杆推到“低速”;用户将控制杆推到“间歇”,然后推到“关”挡风玻璃雨刷在“关”位置,“刻度盘”在位置1,雨刷速度为0事件序列用户行动系统应答123456将控制杆推到“间歇”将刻度盘转到2将刻度盘转到3将控制杆推到“

48、低速”将控制杆推到“间歇”将控制杆推到“关”雨刷速度为4雨刷速度为6雨刷速度为12雨刷速度为30雨刷速度为12雨刷速度为0测试用例:class testScenario wiperSpeed leverPos dialPos step1OK boolean step2OK boolean step3OK boolean step4OK boolean step5OK boolean step6OK booleanmain() windshieldWiper testCase(0,Off,1) testCase.senseLeverUp() wiperSpeed= testCase.getWip

49、erSpeed() if wiperSpeed = 4 Then step1OK = Pass Else step1OK = Fail EndiftestCase.senseDialUp()wiperSpeed= testCase.getWiperSpeed()if wiperSpeed = 6 Then step2OK = Pass Else step2OK = FailEndiftestCase.senseDialUp()wiperSpeed= testCase.getWiperSpeed()if wiperSpeed = 12 Then step3OK = Pass Else step3

50、OK = FailEndiftestCase.senseLeverUp()wiperSpeed= testCase.getWiperSpeed()if wiperSpeed = 30 Then step4OK = Pass Else step4OK = FailEndif测试程序:testCase.senseLeverDown()wiperSpeed= testCase.getWiperSpeed()if wiperSpeed = 12 Then step5OK = Pass Else step2OK = FailEndiftestCase.senseLeverDown()wiperSpeed

51、= testCase.getWiperSpeed()if wiperSpeed = 0 Then step6OK = Pass Else step6OK = FailEndif6.5 面向对象的集成测试因为面向对象软件没有层次的控制结构,传统的自顶向下和自底向上的集成策略是没有意义的,类之间的相互依赖及其紧密,使其根本无法在编译不完全的程序上对类进行测试。因此,面向对象集成测试通常需要在整个程序编译完成后进行。此外,面向对象程序具有动态特性,程序的控制流往往无法确定,所以也只能对整个编译后的程序做基于黑盒的集成测试。面向对象的集成测试能够检测出相对独立的单元测试无法检测出的那些类相互作用时才会

52、产生的错误。单元测试可以保证成员函数行为的正确性,集成测试则只关注于系统的结构和内部的相互作用。面向对象的集成测试(续)面向对象集成测试可以分成两步进行:先进行静态测试,再进行动态测试。测试较为复杂。静态测试主要针对程序结构进行,检测程序结构是否符合设计要求。现在常用的一些测试软件都能提供一种称为 “可逆性工程”的功能,即通过源程序得到类关系图和函数功能调用关系图。将“可逆性工程”得到的结果与OOD的结果相比较,以检测OOP是否达到了设计要求。动态测试则测试与每个动态语境有关的消息。设计测试用例时,通常需要上述的功能调用关系图、类关系图或实体关系图为参考,确定不需要被重复测试的部分,从而优化测

53、试用例,使得进行的测试能够达到一定覆盖标准。一、集成测试的UML支持以方法为单元的集成测试通常需要进行两级集成:一是将成员函数集成到完整类中;二是将类与其它类集成。这里讨论以类为单元的方法-更常见;以类为单元的测试完成后需要恢复被扁平化的类。UML协同图和序列图是集成测试的基础。 UML在系统层描述类定义和类组成。UML协同图显示类间信息传输,支持成对集成和相邻集成。例:o-oCalendar协同图(类似单元调用图)。testItDateYearMonthDay1:Create2:increment3:getYear1:Create2:increment3:printDate1:Create2

54、:increment3:setMonth4:getMonth1:Create2:increment3:setDay4:getDay1:isLeap1:getMonthSize图18-1 o-oCalendar 的协同图根据协同图,可以得到一些要集成的类对:testIt和Date,为Year、Month和Day建立桩。以协同图为基础的面向对象集成测试的缺点是UML描述类行为的状态图很难合并,使较高层次的测试困难。类的相邻集成会降低桩工作量,但缺陷隔离困难,测试用例失败,则必须在更多的类中寻找缺陷。序列图以时间先后表示类的操作即类的时间路径。箭头标号表示类按时间顺序发送的消息。例: o-oCale

55、ndar的printDate序列图。testItDate:testdateDay:dMonth:mYear:y时间1:printDate()2:getMonth()3:getDay()4:getYear()图18-2 printDate的序列图测试伪代码:testDriver m.setMonth(1) d.setDay(15) y.setYear(2002) Output(“expected value is 1/15/2002”) Output(“actual output is”) testdate.printDate()End testDriver面向对象软件的MM-路径是由消息连接起

56、来的方法执行序列。原子系统功能(ASF):从端口输入事件开始到端口输出事件结束的MM-路径。ASF测试是集成测试和系统测试的交叉点,可在两个层次上测试ASF。例: o-oCalendar伪代码 消息图(图18-3) 二、面向对象软件的MM-路径testitMainDateDate()Increment()printDate()DayDay()setCurrentPos()increment()setDay()getDay()MonthMonth()setCurrentPos()increment()setMonth()getMonth YearYear()setCurrentPos()incr

57、ement()getYear()isLeap()m1m2m3m6m5m4m7m11m8m9getMonthSize()m13m10m14m15m16m17m20m18m19m21图18-3 o-oCalendar中的消息m12比协同图更详细。显示了每个消息的源方法和目的方法,而不只是类。实例化(2002年1月15日)Date的部分MM-路径伪代码和路径图实例化(2002年4月30日)Date并计算第二天的部分MM-路径伪代码和路径图基于MM-路径有向图分析选择o-oCalendar的集成测试用例最低限度需要覆盖所有消息的MM-路径集;13个基于决策表的功能测试用例构成了透彻的集成测试用例集合。

58、可以寻找MM-路径,确保所有消息被遍历。测试用例MonthDayYear预期输出Tes6/2001Test463020041/7/2004Test56312001不可能Test69116200417/1/2004Test1013120011/2/2001Test11141216200417/12/2004Tes1/2002Test16216200417/2/2004Tes2/2004Test1822820011/3/2001Test1922920041/3/2004Test202292001不可能Test212223

59、02004不可能13个基于决策表的功能测试用例testitMainDateDate()Increment()printDate()DayDay()setCurrentPos()increment()setDay()getDay()MonthMonth()setCurrentPos()increment()setMonth()getMonth YearYear()setCurrentPos()increment()getYear()isLeap()m1m6m5getMonthSize()m15m16m18m19m21图18-4 实例化Date(2002年1月15日)的MM-路径m4testitM

60、ainDateDate()Increment()printDate()DayDay()setCurrentPos()increment()setDay()getDay()MonthMonth()setCurrentPos()increment()setMonth()getMonth YearYear()setCurrentPos()increment()getYear()isLeap()m2m11m8getMonthSize()m7m17m20图18-5 Date.increment (2002年4月30日)的MM-路径6.6 面向对象的系统测试 通过单元测试和集成测试,仅能保证软件开发的功能

温馨提示

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

评论

0/150

提交评论