7.3.2 面向对象测试
面向对象技术是目前一种主流的软件开发技术,已经基本代替了面向过程开发方法,被看成是解决软件危机的一种先进技术。但是无论采取什么样的方法开发软件,软件高质量的要求不会改变,因而软件测试的目标也不会改变。
面向对象的主要特性包括封装、继承、多态等,这些特性充分体现了分解、抽象、模块化、信息隐蔽等思想,使得软件的复用性提高,有效地控制了软件的复杂性,从而提高了生产效率,缩短了生产时间。然而,这些特性同时也带来了传统语言设计不可能引发的错误。显然,这些错误应用传统的软件测试方法、技术或经验很难发现。因此针对面向对象软件,要想达到测试的真正目的,就必须改变测试的策略和方法。
封装是对数据的隐藏,其他对象只能通过指定的操作访问和修改数据,这就降低了传统方法对数据非法操作的可能性,这一点是可以简化对数据的测试。继承是面向对象的重要特性,它提高了代码的复用,然而错误也会以同样的方式被复用,这无疑给测试带来了困难。例如,在面向过程程序中,对函数y=Fun(x)的测试,只需考虑这个函数本身的行为特点;而在面向对象程序中,却必须同时考虑基类函数(Base::Fun())的行为和继承类函数(Derived::Fun())的行为。多态使得一个对象在不同上、下文条件下具有不同的意义或用法,多态属于运行时的问题,它无疑为程序提供了强大的处理能力,但多态行为的复杂性也给测试带来了前所未有的挑战。面向对象将系统的功能分解到各个类中实现,这种思想就使得软件的每一个错误都可以精确定位到某一个具体的类上;同时,对象间通过消息传递来协同工作,因此仅仅测试单个类的行为特性是远远不够的,还必须进行对象间的交互测试。针对面向对象系统的主要特征和开发特点,应该有一种新的测试模型。
1.面向对象测试模型
面向对象的开发模型突破了传统的瀑布模型,将面向对象系统的开发分为面向对象分析(OOA)、面向对象设计(OOD)和面向对象编程(OOP)等3个阶段。分析阶段产生整个问题空间的抽象描述,在此基础上进一步归纳和设计出适用于面向对象编程语言的类和类结构,最后编码形成代码。采用这种开发模型能有效地将分析设计的文本或图表代码化,不断适应用户需求的变动。针对这种开发模型,结合传统的测试步骤的划分,下面介绍一种将开发阶段的测试与编码完成后的单元测试、集成测试、确认测试等测试工作结合成为一个整体测试的测试模型。
面向对象分析的测试和面向对象设计的测试是对分析结果和设计结果的测试,主要是针对分析设计产生的文本,是软件开发前期的关键性测试。面向对象编程的测试主要针对编程风格和程序代码实现进行测试,其主要的测试内容在面向对象单元测试和面向对象集成测试中体现。面向对象单元测试是对程序内部具体单一的功能模块的测试,是进行面向对象集成测试的基础。面向对象集成测试主要对系统内部的相互关系和服务进行测试,面向对象集成测试不但要基于面向对象单元测试,更要参见面向对象设计或面向对象设计的测试结果。面向对象系统测试是基于面向对象集成测试的最后阶段的测试,主要以用户需求为测试标准,需要借鉴面向对象分析或面向对象分析的测试结果。
上述各阶段的测试构成了一个相互作用的整体,但是各个测试的主体、方向和方法各不相同。接下来将介绍面向对象的面向对象分析的测试、面向对象设计的测试、面向对象编程的测试、面向对象的单元测试、面向对象的集成测试和面向对象的系统测试。
1)面向对象分析的测试
面向对象分析是把E-R图和语义网络模型,即信息造型中的概念与面向对象程序设计语言中的重要概念结合在一起而形成的分析方法,最后通常是得到问题空间的图表形式的描述。面向对象分析直接映射问题空间,全面地将问题空间中实现功能的现实抽象化。将问题空间中的实例抽象为对象,用对象的结构反映问题空间的复杂实例和复杂关系,用属性和方法表示实例的特征和行为。面向对象分析的结果是为后面阶段类的选定和实现、类层次结构的组织和实现提供平台。因此,面向对象分析对问题空间分析抽象的不完整,最终会影响软件的功能实现,导致软件开发后期出现大量不可避免的修补工作;而一些冗余的对象或结构会影响类的选定和程序的整体结构,或增加程序员不必要的工作量。因此,面向对象分析的测试的重点在于其完整性和冗余性。
面向对象分析的测试是一个不可分割的系统过程。其测试划分为以下4方面。
(1)对对象的测试。
认定组成系统的对象是否全面,问题域中所有涉及的事物是否都被反映出来,对象的名称是否准确、适用。
(2)对对象的属性和方法的测试。
认定的对象是否具有多个属性和方法,如果只有一个属性或方法的对象是否可以作为其他对象的属性或方法,而不认为是一个独立的对象;是否对象具有相似的共同属性或服务,是否可以抽象出一个共同的基类来表现这种特征;每个属性的定义是否完整,属性能否不依赖其他属性独立存在,属性的位置是否恰当,是定义在基类中还是定义在派生类中合适;定义的操作是否重复,是否定义了能够得到的操作;等等。
(3)对对象外部联系的测试。
对于一般-特殊关系,是否在问题域中含有不同于其他对象的特殊特征,是否需要派生下一层的对象,是否能够抽象更一般的上层对象。对于整体-部分关系,需要考虑在问题域中是否遗漏了有用的对象,各个组成部分是否能组装成有意义的整体对象。
(4)对对象之间交互的测试。
对象交互过程中是否对所有的消息都进行了定义,是否具有合理的实现过程。沿着消息关联执行的线程是否合理,是否符合现实过程等。
2)面向对象设计的测试
面向对象设计则以面向对象分析为基础归纳出类,并建立类结构或进一步构造成类库,实现分析结果对问题空间的抽象。面向对象设计归纳的类,可以是对象简单的延续,也可以是不同对象的相同或相似的服务。由此可见,面向对象设计是在面向对象分析上进行了细化和更高层的抽象,所以两者的界限通常是难以严格区分的。面向对象设计确定类和类结构不仅是为了满足当前需求分析的要求,更重要的是通过重新组合或加以适当的补充,能方便实现功能的重用和扩充,以不断适应用户的要求。因此,对面向对象设计的测试,建议针对功能的实现和重用及对面向对象设计结果的拓展,下面从3个方面加以考虑。
(1)对认定的类的测试。
面向对象设计认定的类可以是面向对象分析中认定的对象,也可以是对象所需服务的抽象,以及对象所具有的属性的抽象。认定的类原则上应该具有一般性,这样才便于维护和重用。测试认定的类需要考虑的因素有:是否涵盖了面向对象分析中所有认定的对象;是否能体现面向对象分析中定义的属性;是否能实现面向对象分析中定义的服务;是否对应着一个含义明确的数据抽象;是否尽可能少地依赖其他类;类中的方法功能是否是独立的、单一的。
(2)对构造的类层次结构的测试。
为能充分发挥面向对象的继承共享特性面向对象设计的类层次结构,通常基于面向对象分析中产生的分类结构的原则来组织,着重体现父类和子类之间的一般性和特殊性。在当前的问题空间,对类层次结构的主要要求是能在解空间构造实现全部功能的结构框架。为此,测试如下几个方面:类层次结构是否涵盖了所有定义的类;是否能体现面向对象分析中所定义的实例关联;是否能实现面向对象分析中所定义的消息关联;子类是否具有父类没有的新特性;子类间的共同特性是否完全在父类中得以体现。
(3)对类库支持的测试。
对类库支持虽然也属于类层次结构的组织问题,但其强调的重点是软件再次开发的重用。由于它并不直接影响当前软件的开发和功能实现,因此,将其单独提出来测试也可作为对高质量类层次结构的评估。对类库支持的测试点如下:一组子类中关于某种含义相同或基本相同的操作,是否有相同的接口(包括名字和参数表);类中的方法、功能是否较单纯,相应的代码行数是否较少(建议为不超过25行);类的层次结构是否是深度大、宽度小。
3)面向对象编程的测试
典型的面向对象程序具有继承、封装和多态的新特性,这使得传统的测试策略必须有所改变。封装是对数据的隐藏,外界只能通过被提供的操作来访问或修改数据,这样降低了数据被任意修改和读/写的可能性,降低了传统程序中对数据非法操作的测试。继承是面向对象程序的重要特点,继承使得代码的重用率提高,同时也使错误传播的概率提高。继承使得传统测试遇到了这样一个难题:对继承的代码究竟应该怎样测试?多态使得面向对象程序对外呈现出强大的处理能力,但同时却使得程序内“同一”函数的行为复杂化,测试时不得不考虑不同类型具体执行的代码和产生的行为。
面向对象程序是把功能的实现分布在类中。能正确实现功能的类,通过消息传递来协同实现设计要求的功能。正是这种面向对象程序风格,将出现的错误能精确地确定在某一具体的类。因此,在面向对象编程阶段,忽略类功能实现的细则,将测试的注意力集中在类功能的实现和相应的面向对象程序风格上,主要体现为以下两个方面。
(1)数据成员是否满足数据封装的要求。
数据封装是数据和数据有关的操作的集合。检查数据成员是否满足数据封装的要求,其基本原则是数据成员是否被外界(数据成员所属的类或子类以外的调用)直接调用。更直观的说,当改变数据成员的结构时,是否影响了类的对外接口,是否会导致相应外界的改动。值得注意的是,有时强制的类型转换会破坏数据的封装特性。
(2)类是否实现了要求的功能。
类所实现的功能都是通过类的成员方法实现的。在测试类的功能实现时,应该首先保证类成员函数的正确性。单独地看待类的成员函数,与面向过程程序中的函数或过程没有本质区别,几乎所有传统的单元测试中所使用的方法,都可在面向对象的单元测试中使用。类函数成员的正确行为只是类能够实现要求的功能基础,类成员函数间的作用和类之间的服务调用是单元测试无法确定的。因此,需要进行面向对象的集成测试。
4)面向对象的单元测试
由于对象的“封装”特性,面向对象软件中单元的概念与传统的结构化软件的模块概念已经有较大的区别。面向对象软件的基本单元是类和对象,包括属性(数据)及处理这些属性的操作(方法或服务)。因此,对于面向对象的软件来说,面向对象的单元测试的含义发生了很大变化,其最小的可测试单元是封装起来的类和对象。一个类可以包含一组不同的操作,而一个特定的操作也可能存在于一组不同的类中。
让我们举例来说明上述论点:考虑一个类层次,操作X在超类中定义并被一组子类继承,每个子类都使用操作X,但是,X调用子类中定义的操作并处理子类的私有属性。由于在不同的子类中使用操作X的环境有微妙的不同,因此有必要在每个子类的语境中测试操作X。这就意味着,当测试面向对象软件时,传统的单元测试方法是无效的,我们不能再孤立地测试操作X。
面向对象的单元测试分为两个层次测试:方法级测试和类级测试。方法级测试主要测试类和对象中所有的操作算法,其测试技术同传统的过程式软件测试相同。类级测试则面临一些新问题,需要考虑属性的数据,需要考虑对象的继承、多态、重载、消息传递等关系。驱动程序和存根程序的概念也相应是一些“驱动对象”和“存根对象”。
5)面向对象的集成测试
传统的集成测试是采用自顶向下或自底向上或两者结合的两头逼近策略,通过用渐增方式集成功能模块进行的测试。但是由于面向对象程序没有层次的控制结构,相互调用的功能也是分散在不同的类中,类通过消息的相互作用申请和提供服务,所以这种集成测试的策略就没有意义了。此外,由于面向对象程序具有动态性,程序的控制流往往难以确定,因此只能做基于黑盒方法的集成测试。
面向对象的集成测试主要关注于系统的结构和内部的相互作用。面向对象软件的集成测试有两种方法。
(1)基于线程的测试。
基于线程的测试是指把响应系统的一个输入或一个事件所需的一组类集成起来进行测试。应当分别集成并测试每个线程,同时为了避免产生副作用再进行回归测试。
(2)基于使用的测试。
基于使用的测试首先测试几乎不使用服务器类的那些类(称为独立类),把独立类都测试完之后,接着测试使用独立类的最下层的类(称为依赖类)。然后,根据依赖类的使用关系,从下到上一个层次一个层次地持续进行测试,直至把整个软件系统测试完为止。
除了上述两种测试方法,集群测试是面向对象软件集成测试的一个步骤。为了检查一群相互协作的类,用精心设计的测试用例,力图发现协作错误。通过研究对象模型可以确定协作类。
为减少测试工作量,在进行集成测试时,可参考类关系图或实体关系图,确定不需要被重复测试的步骤,从而优化测试用例,使测试能够达到一定的标准。
6)面向对象的系统测试
面向对象的单元测试和集成测试仅能确认软件开发的功能是否正确,但是不能确认在实际运行时,它是否满足用户要求,是否大量存在与实际使用条件下的各种应用相矛盾的错误,为此,还必须经过规范的系统测试。系统测试通常包含以下5种。
(1)功能和性能测试。
功能和性能测试用于测试软件是否满足开发要求,是否能够提供设计所描述的功能,用户的需求是否都得到满足,用户界面是否友好等。测试人员要认真研究动态模型和描述系统行为的脚本,以确定最有可能发现用户交互需求错误的情景。功能测试是系统测试最常用和必需的测试,通常还会以正式的软件说明书作为测试标准。在嵌入式和实时系统等实时要求比较高的系统中,软件运行性能是测试的重要内容。性能测试常和压力测试同时进行,需要建立特定的硬件环境和软件测试环境,在比较苛刻的环境中测试软件的执行效率和故障情况。
(2)强度测试。
强度测试用于测试系统的最高实际限度,即软件在一些超负荷的情况下功能的实现情况。强度测试是在一种超常数量、频率、容量方式下检测系统是否能够正常运行。
(3)安全测试。
安全测试用于验证安装在系统内的保护机构确实能够对系统进行保护,使之不受各种非常因素的干扰。安全测试时需要设计一些测试用例,试图突破系统的安全保密措施,检验系统是否有安全保密的漏洞。
(4)恢复测试。
恢复测试用于采用人工干扰的方法使软件出错,中断使用,检测系统的恢复能力,特别是通信系统。恢复测试时,应该参考性能测试的相关测试指标。
(5)安装/卸载测试。
安装/卸载测试用于系统测试,需要结合需求分析对被测的软件进行安装/卸载的测试,并设计测试用例。
2.面向对象测试用例设计
测试方案的设计是软件测试阶段的关键技术问题。所谓测试方案包括预定要测试的功能、应该输入的测试数据和预期的结果,最困难的是设计测试用的输入数据,即测试用例。
目前,面向对象软件的测试用例的设计方法还处在研究、发展阶段。与传统软件测试不同的是,面向对象测试关注于适当的操作序列以检查类的状态。
1)面向对象概念对测试用例设计的影响
封装性和继承性是类的重要特性,这给面向对象的软件开发带来了很多好处,同时它又对面向对象的软件测试带来了负面影响。
类的属性和操作是被封装的,而测试需要了解对象的详细状态。同时,需要考虑当改变数据成员的结构时,是否影响了类的对外接口,是否导致相应外界的改动。例如,强制的类型转换会破坏数据的封装性,请看下面的这段程序:

程序中,p的数据成员可以通过q被随意访问。
此外,继承不会减少对子类的测试,相反,会使测试过程更加复杂化。因此,继承也给测试用例的设计速度带来了负面影响。当父类与子类的环境不同时,父类的测试用例对子类没有什么使用价值,必须为子类设计新的测试用例。
在设计面向对象的测试用例时应注意下面三点。
(1)继承的成员函数需要测试。
对于在父类中已经测试过的成员函数,根据具体情况仍需在子类中重新测试。一般在下面两种情况下要对成员函数重新进行测试:
①继承的成员函数在子类中有所改动;
②成员函数调用了改动过的成员函数。
(2)子类的测试用例可以参照父类。
例如,有两个不同的成员函数的定义如下。

在原有的测试上,对son::B()的测试只需作如下改动:将value==0的测试结果期望改动,并增加value==99这一条件的测试。
(3)设计测试用例时,不但要设计确认类功能满足的输入,而且还应有意识地设计一些被禁止的用例,确认类是否有不合法的行为产生。
2)测试类的方法
一般为类设计测试用例时,需要按照以下步骤进行:
①确定覆盖标准;
②利用结构关系图确定待测试类的所有关联;
③根据程序中类的对象构造测试用例,确认使用输入激发类的状态,使用类的服务和期望产生的行为,等等。
值得注意的是,设计测试用例时,不但要设计确认类功能满足的输入,还应该有意识地设计一些被禁止的用例,以确认类是否有不合法的行为产生,如发送与类状态不相适应的消息,要求不相适应的服务等。下面介绍几种常用的类测试用例的设计方法。
(1)随机测试。
如果一个类有多个操作(功能),那么这些操作(功能)序列就有多种排列。而这种不变化的操作序列可随机产生,用这种可随机排列的序列来检查不同类实例的生存史称为随机测试。
例如,前面的教学信息管理系统,其中有一个类:教师。该教师的操作有登录、添加信息、修改信息、删除信息、查询信息、总记录数、注销等。这些操作中的每一项都可用于计算,但登录和注销必须在其他计算的任何一个操作前后执行。即使登录和注销有这种限制,这些操作仍有许多排列。所以一个不同变化的操作序列可因应用不同而随机产生。如一个教师实例的最小行为转换器可包括以下操作:
登录+查询+注销
这表示了对学生信息的最小测试序列。然而,在下面序列中可能发生大量的其他行为:
登录+查询+[添加修改删除查询总记录数]+注销
由此可以随即产生一系列不同的操作序列,例如:
测试用例1:登录+查询+添加+总记录数+查询+删除+注销
测试用例2:登录+查询+修改+添加+总记录数+查询+注销
可以执行这些测试和其他的随机顺序测试,以测试不同的类实例生存史。
(2)划分测试。
与传统测试软件采用等价划分方法类似,采用划分测试(Partition Testing)方法可以减少测试类时所需测试用例的数量。首先,把输入和输出分类,然后设计测试用例以测试划分出的每个类别。下面介绍划分类别的方法。
①基于状态的划分。
这种方法根据类操作改变类状态的能力来划分类操作。这里仍以教师类为例,改变状态的操作有添加、修改和删除,不改变状态的有查询和总记录数。如果测试按检查类操作是否改变类状态来设计,则结果如下。
测试用例1:执行操作改变状态(在最小测试序列中的操作除外)
登录+查询+添加+修改+删除+注销
测试用例2:执行操作不改变状态(在最小测试序列中的操作除外)
登录+查询+总记录数+注销
②基于属性的划分。
这种方法根据类操作使用的属性来划分类操作。对于教师类,属性总记录数被分割为三种操作:用总记录数的操作、修改总记录数的操作、不用也不修改总记录数的操作。这样,测试序列就可按每种分割来设计。
③基于功能的划分。
这种方法根据类操作所完成的功能来划分类操作。在教师类的操作中,可以分割为
初始操作:登录
计算操作:添加、修改和删除
查询操作:查询、总记录数
终止操作:注销
(3)基于故障的测试。
基于故障的测试的目的是设计最有可能发现“似乎可能的故障”的测试。例如,软件工程师经常在问题的边界处犯错误。因此,当测试SQRT(计算平方根)操作(该操作对负数返回错误)时,应着重检查边界情况:一个靠近零的负数和零本身。其中,“零本身”用于检查程序员是否犯了如下错误。
把正确的语句:

误写成:

对于每个可能的故障,应设计出迫使不正确的表达式失败的测试用例。当然,这些技术的有效性在很大程度上依赖于测试人员的经验和如何感觉“似乎可能的故障”。如果面向对象软件中的真实故障被感觉为“难以置信的故障”,则本方法实质上不比任何随机测试技术好。然而,如果仔细研究了分析模型和设计模型,对那些可能出错的地方进行了深入分析,那么基于故障的测试可以以相对低的工作量来发现大量的错误。
(4)基于场景的测试设计。
基于场景的测试侧重于关心用户做什么,它捕获用户必须完成的任务,然后应用它们或它们的变体作为测试。基于场景的测试将揭示交互错误,为此,测试用例必须比基于故障的测试更复杂和更现实。例如,教学信息管理系统软件的基于场景测试的用例设计。
测试用例:添加学生信息。
背景:添加学生信息,并能从查询中发现添加的信息。
其执行事件序列:添加学生信息;对添加的学生信息进行查询。
测试人员希望可以查询到添加的学生信息,否则说明添加学生信息的操作产生了错误。
3.面向对象测试工具简介
面向对象测试是整个软件生存周期中至关重要的环节,没有进行测试的软件系统是危险的,甚至是有害的,不能投入实际使用。软件测试必须是合理的、有效的,并能够尽可能的发现系统各阶段错误,高效的面向对象测试工具是面向对象测试的有利保证。下面介绍几种面向对象测试的工具。
1)Logiscope
Logiscope是法国Telelogic公司推出的专用于软件质量保证和软件测试的产品,其主要功能是对软件做质量分析和测试以保证软件的质量,并可做认证、反向工程和维护,特别是针对高可靠性要求和高安全性要求的软件项目和工程。
Logiscope应用于软件的整个生存周期,它贯穿于软件需求分析阶段、设计阶段、代码开发阶段、软件测试阶段(代码审查、单元测试、集成测试和系统测试)、软件维护阶段的质量验证要求。
在设计和开发阶段,使用Logiscope可以对软件的体系结构和编码进行确认。可以在尽可能早的阶段检测那些关键部分,寻找潜在的错误,并在禁止更改和维护工作之前做更多的工作。在构造软件的同时定义测试策略。可帮助编写符合企业标准的文档,改进不同开发组之间的交流;在测试阶段用Logiscope使测试更加有效。可针对软件结构度量测试覆盖的完整性,评估测试效率,确保满足要求的测试等级。特别是Logiscope还可以自动生成相应的测试分析报告,在软件的维护阶段用Logiscope验证已有的软件是不是质量已得到保证的软件。对于状态不确定的软件,Logiscope可以迅速提交软件质量的评估报告,大幅度地减少理解性工作,避免非受控修改引发的错误。
Logiscope包括以下3个工具。
(1)Logiscope RuleChecker。
Logiscope RuleChecker根据工程中定义的编程规则自动检查软件代码中的错误,并可直接定位错误;包含大量的标准规则,用户也可定制创建规则,并自动生成测试报告。
(2)Logiscope Audit。
Logiscope Audit定位错误模块,可评估软件质量及复杂程度;提供代码的直观描述,自动生成软件文档。
(3)Logiscope TestChecker。
测试覆盖分析,显示没有测试的代码路径,基于源码结构进行分析。直接反馈测试效率和测试进度,协助进行衰退测试。既可在主机上测试,也可在目标板上测试。支持不同的实时操作系统、支持多线程,可累积合并多次测试结果,自动鉴别低效测试和衰退测试,自动生成定制报告和文档。
目前Logiscope产品在全世界的26个国家的众多国际知名企业中得到了广泛的应用,其用户涉及通信、电子、航空、国防、汽车、运输、能源及工业过程控制等众多领域。
2)LoadRunner
LoadRunner是一种预测系统行为和性能的工业标准级负载测试工具。通过模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadRunner能够对整个企业架构进行测试。通过使用LoadRunner,企业能最大限度地缩短测试时间,优化性能和加速应用系统的发布周期。
目前企业的网络应用环境都必须支持大量用户,网络体系架构含有各类应用环境,且由不同供应商提供软件和硬件产品。难以预知的用户负载和越来越复杂的应用环境,使公司时时担心发生用户响应速度过慢、系统崩溃等问题。这些都不可避免地导致公司利益的损失。
LoadRunner是一种适用于各种体系架构的自动负载测试工具,它能预测系统行为并优化系统性能。LoadRunner的测试对象是整个企业的系统,它通过模拟实际用户的操作行为和实行实时性能监测来帮助测试人员更快地查找和发现问题。此外,LoadRunner能支持广泛的协议和技术,为特殊环境提供特殊的解决方案。
对于一个具体的测试案例而言,首先应该创建虚拟用户。使用LoadRunner的Virtual User Generator创建系统负载。该引擎能够生成虚拟用户,以虚拟用户的方式模拟真实用户的业务操作行为。它先记录下业务流程(如下订单或机票预订),然后将其转化为测试脚本。利用虚拟用户,可以在Windows、UNIX或Linux操作系统上同时产生成千上万用户访问,所以LoadRunner能极大地减少负载测试所需的硬件和人力资源。另外,LoadRunner 的TurboLoad专利技术能提供很高的适应性。TurboLoad可以产生每天几十万在线用户和数以百万计的点击数的负载。
用Virtual User Generator建立测试脚本后,可以对其进行参数化操作,这一操作能让用户利用几套不同的实际发生数据来测试应用程序,从而反映出本系统的负载能力。以一个订单输入过程为例,参数化操作可将记录中的固定数据(如订单号和客户名)用可变值来代替。在这些变量内随意输入可能的订单号和客户名,来匹配多个实际用户的操作行为。
LoadRunner通过它的Data Wizard来自动实现其测试数据的参数化。Data Wizard直接连接到数据库服务器,从中可以获取所需的数据,并直接将其输入到测试脚本。这样避免了人工处理数据的复杂性。
为了进一步确定Virtual User能够模拟真实用户,可利用LoadRunner控制某些行为特性。例如,只需要点击鼠标,就能轻易控制交易数量、交易频率和连接速度等。
建立Virtual Users后,还需要设定负载方案、业务流程组合和虚拟用户数量。用LoadRunner的Controller能很快组织起多用户的测试方案。Controller的Rendezvous提供了一个互动的环境,在其中既能建立起持续且循环的负载,又能管理和驱动负载测试方案。而且,还可以利用它的日程计划服务来定义用户在什么时间访问系统以产生负载。这样,就能将测试过程自动化。同样,还可以用Controller来限定负载方案,在这个方案中所有用户同时执行一个动作,如登录到一个库存应用程序来模拟峰值负载的情况。另外,在能监测系统构架中,通过各个组件(包括服务器、数据库、网络设备等)的性能来帮助用户决定系统的配置。
LoadRunner通过AutoLoad技术,提供更多的测试灵活性。使用AutoLoad可以根据当前的用户人数事先设定测试目标,优化测试流程。例如,目标可以是确定该应用系统承受的每秒点击数或每秒的交易量。
LoadRunner内含集成的实时监测器,在负载测试过程的任意时间,用户都可以观察到应用系统的运行性能。这些性能监测器能够实时显示交易性能数据(如响应时间)和其他系统组件,包括Application Server、Web Server、网络设备和数据库等的实时性能。同时,利用LoadRunner的ContentCheck TM,可以判断负载下的应用程序功能正常与否。ContentCheck在Virtual Users运行时,检测应用程序的网络数据包内容,从中确定是否有错误内容传送出去。它的实时浏览器可以帮助测试人员从终端用户的角度观察程序的性能状况。
一旦测试完毕后,LoadRunner收集汇总所有测试数据,并为用户提供高级的分析和报告工具,以便迅速查找到性能问题并追溯缘由。使用LoadRunner的Web交易细节监测器可以了解到将所有的图像、框架和文本下载到每一个网页上所需的时间。例如,这个交易细节分析机制能够分析是否因为一个大尺寸的图形文件,或是第三方的数据组件,造成应用系统的运行速度减慢。另外,Web交易细节监测器分解用于客户端、网络和服务器上端到端的反应时间,便于确认问题,定位查找真正出错的组件。例如,可以将网络延时进行分解,以判断DNS(Domain Name System)解析时间、连接服务器或SSL(Secure Sockets Layer)认证所花费的时间。通过使用LoadRunner的分析工具,就能很快地查找到出错的位置和原因并作出相应的调整。
3)WinRunner
Mercury Interactive公司的WinRunner是一种企业级的功能测试工具,用于检测应用程序是否能够达到预期的功能并能正常运行。通过自动录制、检测和回放用户的应用操作,WinRunner能够有效地帮助测试人员对复杂的企业级应用的不同发布版本进行测试,提高测试人员的工作效率和质量,确保跨平台的、复杂的企业级应用无故障地发布及长期稳定地运行。
WinRunner测试工具能够自动完成应用程序的功能性测试,确保复杂的企业级应用在不同的环境下都能正常可靠地运行。以下是它的功能。
(1)轻松创建测试。
用WinRunner创建一个测试,只需点击鼠标和敲击键盘完成一个标准的业务操作流程,WinRunner自动记录操作并生成所需的脚本代码。这样即使计算机技术知识有限的业务用户也能轻松创建完整的测试。它还可以直接修改测试脚本以满足各种复杂测试的需求。WinRunner提供这两种测试创建方式,满足测试团队中业务用户和专业技术人员的不同需求。
(2)插入检查点。
在记录一个测试的过程中,可以插入检查点检查在某个时刻/状态下应用程序是否运行正常。在插入检查点后WinRunner会收集一套数据指标,在测试运行时对其一一验证。WinRunner提供几种不同类型的检查点,包括文本、GUI、位图和数据库。例如,用一个位图检查点,你可以检查公司的图标是否出现于指定位置。
(3)检验数据。
除了创建和运行测试外,WinRunner还能验证数据库的数值,从而确保业务交易的准确性。例如,在创建测试时,可以设定哪些数据库表和记录需要检测;在测试运行时,测试程序就会自动核对数据库内的实际数值和预期的数值。WinRunner自动显示检测结果,在有更新、删除、插入的记录上突出显示以引起注意。
(4)增强测试。
为了彻底、全面地测试一个应用程序,需要使用不同类型的数据来测试。WinRunner的数据驱动向导(Data Driver Wizard)可以让你简单地点击鼠标,就可以把一个业务流程测试转化为数据驱动测试,从而反映多个用户各自独特且真实的行为。