8软件工程第九章大同大学-4

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第7节面向对象测试面向对象测试的特点面向对象的测试策略面向对象软件的测试用例设计RUP的测试活动面向对象测试的特点面向对象测试的整体目标(以最小的工作量发现最大数量的错误)与传统软件测试的目标是一致的。但是OO程序的性质改变了测试策略与战术。1、传统测试主要是基于程序运行过程的,即选择一组输入数据运行被测程序,通过比较实际结果与预期结果从而判断程序是否有错。而OO程序中的对象通过发送消息启动相应的操作,并且通过修改对象的状态达到转化系统运行状态的目的,同时,在系统中还可能存在并发活动的对象。应此传统的测试方法不再适应。2、传统程序的复用以调用公共模块为主,运行环境是连续的。而面向对象复用很多是用继承实现的,子类继承过来的同名操作有新的语境,必须要重新测试。随着继承层次的加深,测试的工作量和难度也随之增加。由继承支持的多态的特性同样给测试带来了难度。3、面向对象软件的开发是渐进、演化的开发,从分析、设计到实现使用相同的语义结构(如类、属性、操作、消息)。因此要扩大测试的视角,对分析模型、设计模型进行测试。例如,在分析模型中定义了一个无用的属性,围绕着这个属性可能会带来以下错误:在分析模型中:•定义了一个与该属性有关的操作:•导致了不正确的类关系:•为共享属性和操作创建了不必要的子类:•为适应该属性和操作刻画了其类和系统的行为。如果问题在分析阶段未被发现,再将错误继续传播,使得设计模型可能存在:•与该类有关的不合适的子系统或任务的划分:•与该无用属性有关操作的算法设计:•与该无用属性有关操作的接口及消息模式。面向对象测试的特点如果问题在设计阶段仍未被检测到,并传送到编码活动中,则大量的工作将被花在生成那些实现一个不必要的属性、不必要的操作、不必要的消息通信以及很多其它相关问题的代码。由于分析设计模型不能被执行,所以不能进行传统意义上的测试。只能通过正式技术复审来检查分析模型和设计模型的一致性。4、面向对象开发工作的演化性使面向对象测试活动也具有演化性。每个构件产生过程中,单元测试随时进行,迭代的每一个构造都要进行集成测试,后期迭代还包括大量的回归测试,迭代结束时进行系统测试。是否设计模式的使用将减轻OO系统的繁重测试?Binder认为每次复用是一个新的使用语境,需要重新谨慎的测试。为了获得OO系统的高可靠性,可能需要更多的而不是更少的测试。面向对象测试的特点面向对象的测试策略传统的测试策略是从小型测试开始,逐步走向大型测试,即从单元测试开始,逐步进入集成测试,最后进行系统测试。在传统测试中,单元测试集中在最小的可编译程序单位(子程序、过程、函数),一旦这些单元都被独立测试后,被集成到程序结构中进行一系列的回归测试,以发现由于模块的接口和新单元加入所导致的副作用而带来的错误。最后,对系统整体进行测试以发现需求中的错误。面向对象软件测试的目标与结构化软件测试的目标相同,都是为了找出软件开发中的错误,提高软件的质量。结构化软件的测试策略是从组成系统的最小单元——模块开始进行测试,然后逐步集成进行小系统测试、系统测试,最后在用户的参与下进行验收测试。面向对象的测试策略1、单元测试(类或对象或组成的小簇)OO语境中,单元的概念发生了变化。封装驱动了类或对象的定义,即每个类或对象封装了属性和操作这些属性的服务,最小的可测试单位不是个体模块,而是封装的类或对象。类包含一组不同的操作,并且某个特殊操作可能作为类的一部分存在(如子类中继承的操作),因此,单元实际上是类或若干相关的类组成的小簇。单元测试不再孤立的测试单个操作(这是传统的单元测试的视角),而是将操作作为类的一部分。命令execute()粘贴命令execute()拷贝命令execute()execute由基类定义并被一组子类继承,每个子类的execute被应用于每个子类定义的私有属性和操作的语境内,因此,仅在基类内测试execute是无效的,应该在每个子类的语境内测试execute。单元测试若用于测试不发生请求的类(如“栈”类,其中操作有:pop(),push(),empty())时,同样要设计驱动程序,封装在一个测试类(包)中,测试类负责运行测试用例并给出结果,每个测试用例用一个操作名表示;单元测试如果测试发生请求的类,则需要设计桩程序,封装在桩类中。例如:面向对象的测试策略单元测试主要使用的图模型是:类图、类的状态图、活动图。2、集成测试(大簇、构件、子系统)这里的构件或子系统应该与系统的体系结构相对应。集成测试主要以检查这些构件、子系统的接口为目的。对于类之间的集成,RogerS.Pressman认为传统的自顶向下和自底向上集成的测试策略没有意义。他提出了两种集成测试策略:(1)基于线程的测试(thread-basedtesting)集成一组相互协作的对某个输入或事件作出响应的类,每个线程被分别测试,并使用回归测试以保证没有副作用产生。(2)基于使用的测试(use-basedtesting)按层次测试系统。先测试不依赖服务器的独立类,如管理和显示数据的类,然后测试依赖独立类的其他类。逐步增加依赖类,直到测试完整个系统。面向对象的测试策略对于子系统之间的集成,如果系统划分为层次结构,则可以按自顶向下或自底向上集成,同时也需设计驱动类和桩类。如:一个OO系统的结构为:用户界面(A)应用逻辑(B)访问数据库(C)网络通信(D)应用系统的一个结构该系统可以采用自顶向下、自底向上或三明治式进行集成测试。见下图。面向对象的测试策略自顶向下自底向上三明治式UI层桩桩UI层应用层桩桩UI层应用层数据库网络数据库层网络层驱动驱动数据库网络应用层驱动驱动UI层桩桩数据库层网络层驱动驱动面向对象的测试策略TestATestBTestCTestDTestA、BTestB、CTestB、DTestA、B、C、D单元测试集成测试集成测试测试过程(UML活动图)集成测试使用的图模型是:顺序图、协作图、活动图(概念层)面向对象的测试策略3、确认测试在确认和系统测试层次,和传统的一样。测试的内容主要集中于用户可见的动作和用户可识别的系统输出(用户可见的功能),以及系统性能等其他需求。测试人员应该根据需求说明和用例模型设计测试用例。确认测试使用的图模型主要是用例图。面向对象的测试策略面向对象软件的测试用例设计传统测试用例设计是由软件的输入、加工、输出视图或个体模块的算法细节驱动的,面向对象测试关注于设计合适的操作序列以测试类的状态和用例的实现。1、传统方法的可用性白盒测试:用于类级别的测试。测试类中封装的操作,检查类的状态以确定是否存在错误。黑盒测试:集成测试、确认测试。构件、子系统是黑盒。测试序列跟踪跨越类协作的操作流。2、类级别测试用例设计(单元测试)着重于单个类及封装的操作。可按照以下方法设计用例:(1)随机测试以银行应用系统为例,简要说明这种测试方法。该系统的account(帐户)类有如下操作:open(打开)、setup(建立)、deposit(存款)、withdraw(取款)、balance(余额)、summarize(清单)、creditLimit(透支限额)、close(关闭)。但问题的性质隐含了一些限制(例如,账号必须在其它操作可应用前被打开,在所有操作完成后被关闭)。一个帐户实例的最小行为生命历史包括下面操作:打开,建立,存款,取款,关闭,表示了帐户的最小测试序列。然而大量的其它行为可能在下面序列中发生:打开,建立,存款,[存款|取款|余额|清单|透支限额]n,取款,关闭一系列操作序列可以随机产生,例如:测试用例1:打开,建立,存款,存款,余额,清单,取款,关闭面向对象软件的测试用例设计测试用例2:打开,建立,存款,取款,存款,余额,透支限额,取款,关闭可随机选取其它的测试序列以测试该类对象不同的生命历史。(2)划分测试(partitiontesting)可以减少测试类所需的测试用例的数量,采用与传统测试的等价划分相同的方式,即输入、输出被分类,为处理每个类别设计测试用例。划分类别的具体方法是:•基于状态的划分基于类操作改变类状态的能力来对类操作分类。类中有的操作改变类的状态(如帐户类中的存款和取款),有的操作不改变类的状态(如余额,清单和透支限额)。因此分别独立测试改变状态的操作和不改变状态的操作。面向对象软件的测试用例设计•基于属性的划分根据操作使用的属性来划分类操作,即使用相同属性的操作划分在一个等价类中。如帐户类中,以透支限额来定义划分,操作被定义成3个类别:①使用透支限额的操作,②修改透支限额的操作,③不使用或不修改透支限额的操作。然后对每个划分设计测试序列。•基于操作类别的划分如在帐户类中的操作可被分类为:初始化操作(打开、建立)、计算操作(存款,取款)、查询操作(余额,清单,透支限额)和终止操作(关闭)。面向对象软件的测试用例设计3、类协作测试用例的设计(集成测试)测试类或构件被组装后相互之间能否正常交互完成指定的功能。使用use-case作为测试的主要驱动,顺序图、协作图为测试提供帮助。和单个类一样,可通过应用随机和划分方法以及基于use-case场景和行为模型导出测试用例。(1)随机测试Kirani等人建议用下面的步骤生成多个随机测试序列:•对每个客户类,用类操作列表生成随机测试序列,这些操作将发送消息给其他服务器。•对生成的每个消息,确定在服务器对象中的协作者类及对应的操作。•对服务器对象中的已经被来自客户对象的消息调用的每个操作,确定该操作向协作者发送的消息。面向对象软件的测试用例设计•对每个消息,确定下一层被调用的操作并结合这些操作到测试序列中。如,某一个应用问题的类协作图如下:对B的随机测试序列可能是x1,x2,…,为了考虑涉及到该测试的协作者,要考虑上述序列中每个操作相关联的消息。设B必须与C协作(需执行x3)以执行x1,B与D协作(需执行x4)以执行x2。因此,对B的测试序列应该是:x1,[x3],x2,[x4],…测试序列跟踪跨越类协作的操作流。基于用例的实现是产生随机测试序列的基础。ABCDEx1,x2,…x3x4面向对象软件的测试用例设计(2)划分测试类似于单个类划分测试方法,但需扩展测试序列以包括那些通过发送给协作类的消息而激活的操作。另一种方法是基于特殊类的接口来划分测试。如上图,B接收来自类A和类E的消息,可以通过将B中的方法划分为服务于A和服务于E的操作来测试。(3)从行为模型导出的测试类的STD可用于帮助导出测试类(和那些与其协作的类)的动态行为的测试序列。下图是银行应用系统帐户类的STD。所涉及的测试应覆盖所有的状态,即操作序列应该导致帐户类的转换穿越所有允许的状态。面向对象软件的测试用例设计测试用例1:打开,存款(初次),取款l(消户),关闭(最小测试序列)测试用例2:打开,存款(初次),存款,余额,透支,取款(消户),关闭测试用例3:打开,存款(初次),存款,取款,帐户资料,取款(消户),关闭建立帐户帐户操作非帐户操作打开存款(初次)存款余额,透支,帐户资料取款(消户)关闭取款面向对象软件的测试用例设计可以使用“宽度优先的方式”遍历STD:一个测试用例测试单个状态转换,当测试新的转换时,仅使用以前被测试过的转换。4、其它需要考虑的问题以上测试用例的设计主要考虑选取合适的操作序列,还要考虑操作的参数,在选择参数时可对参数划分等价类,每个输入参数属于一个等价类,同时还需考虑参数的边界情况。面向对象软件的测试用例设计RUP的测试活动RUP建立的测试活动主要是执行并评估测试模型所描述的测试。其中,测试模型是包括以下内容的集合:•测试用例:可设计一张表:每一行是一个测试用例,每一列有用例的输入数据、预期结果、实际结果和测试条件。•测试规程:详细描述了怎样使用测试用例。一个测试规程可能用于不同的测试用例,但有时一个测试用例可能需要多个测试规程。(多对多关系)•测试构件:为了实现系统测试自动化而设计的程序构件,有时也称“测试驱动程序”。RUP的测试活动具体有以下几方面:1、制定测试计划规划一次迭代中的测试工作,包括:•描述测试策略•估算测试工

1 / 36
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功