TestComplete的对象驱动测试方法
陈能技
2007-9-4
自动化测试脚本的创建其实主要是编程任务。如果测试不需要加载数据,主要目的是测试一个对象而已(例如一个窗体),那么你可以写一两个脚本使用几个本地变量或全局变量就可以了。但是,大部分测试项目会很大,包括很多脚本单元并使用很多的测试数据,在这种情况下,如果使用面向对象的方式编程就会变得逻辑上简单点。例如为每个测试窗体创建一个对象,使用这些对象的方法和属性来测试窗体上的控件。
Object-Driven Testing(ODT)
有时候,你不仅需要创建对象,还需要创建复杂的对象层次结构,对象属性保持着数据结构、数组、对其它对象的引用等。为了支持这种对象创建能力,TC使用ODT来解决。
下面是ODT的逻辑结构层次图:
ODT允许你创建常用的数据变量(整型、字符串、日期等),也支持自定义对象和多维数组。每个数组元素可以存储一个普通值,一个数组或对其它对象的引用。从而创建任何复杂的对象层次。
可以直接创建添加自定义数据结构和对象,也可以通过脚本方式使用ODT对象创建。
ODT使用规则
1、 数据组织成组。每一组保持一个集合的变量,每个变量可存储普通值、数组或对象。通过ODT的Data项来配置数据。在脚本中通过Data对象的属性和方法来创建或访问数据。
2、 所有对象必须基于类来创建。通过ODT的Classes项来创建类,或在脚本中使用Classes对象的属性和方法来访问或创建类。也就是说,在创建对象之前,必须为其创建一个类。
3、 一个对象方法就是一个脚本程序,它与一般的脚本程序的区别在于它可以访问对象的属性。这样做能减少程序的参数数量。
通过脚本创建Classes和Object
Classes和Object是ODT的重要组成部分,在使用之前必须创建好,可以界面上直观地添加创建,也可以通过脚本方式创建。
使用Classes.Declare方法创建新的类,例如,下面脚本创建了一个名为ClsNotepadTest的类:
TestClassObj := ODT.Classes.Declare('ClsNotepadTest');
创建好类之后,我们就可以添加类的方法和属性了,例如,下面脚本往ClsNotepadTest类添加了几个方法和属性:
TestClassObj := ODT.Classes.Declare('ClsNotepadTest');
// Adds the Init method to the class
TestClassObj.AddMethod('Init', 'MainUnit.ClsNotepadTest_Init');
// Adds the ID property
TestClassObj.AddProperty('ID', '');
// Adds the Files property
TestClassObj.AddPropOfArrayType('Files');
注意,添加方法时需要指定参数,第一个是方法的名称,第二个是指定哪个脚本程序作为方法使用。你也可以不指定第二个参数,但是这样的话,你必须为这个类的每个对象指定脚本程序。可以为每个对象指定不同的脚本程序,这样允许你创建相同名称但是不同操作的方法。
创建好类后,就可以创建这个类的对象了。例如以下脚本创建ClsNotePadTest类的一个对象:
TestObj := ODT.Classes.New('ClsNotepadTest');
创建好对象后,我们可以调用它的方法或修改它的属性。例如,下面脚本修改ClsNotePadTest对象的ID属性:
TestObj.ID := 'ReleaseTest';
在作为对象方法的脚本程序中,VBScript、Jscript、C++Script使用关键字This,DelphiScript中使用Self关键字来访问它所属的对象的属性和方法。例如,以下是CLsNotepadTest对象的Init方法的脚本:
procedure Init;
var
i, FileObj : OleVariant;
begin
for i := 0 to Self.Files.Count - 1 do
begin
FileObj := Self.Files[i];
// Perform some actions over the ClsFile object ...
end;
end;
注意:This和Self关键字只能在代表对象方法的脚本程序中才能使用。在对象方法之外的脚本程序中不能使用。
控制对象驱动测试
大部分自定义对象拥有一个树型结构。树的根节点是ODT.Data对象,树节点是变量、自定义对象、数组等。测试脚本可以按一定的顺序访问和调用对象方法。测试脚本的Main函数需要初始化这个调用顺序。
ODT.Data.Run方法会从对象树的开头开始按以下方式顺序执行:
1、 如果节点(data group、variable、object、array等)存储了普通值(string、integer等),则不执行任何内容,跳到同一层次的下一节点。
2、 如果节点存储了数组,Run方法检查数组的每一项
2.1、如果某项存储的是普通变量,则不执行,跳到下一项
2.2、如果某项存储的是对象,则按3的方式执行
2.3、如果某项存储的是数组,则按2的方式执行
3、 如果节点存储的是对象,Run方法按下面方式执行
3.1、顺序执行所有指定为Init的对象方法
3.2、分析对象的属性,如果属性保持了一个对象,则Run方法处理这个对象(执行它的方法和按3.2处理它的属性);如果属性保持了一个数组,则遍历数组中的每一项进行处理;如果属性保持了一个普通值,则忽略不处理。
3.3、顺序调用非Init方法
所有使用ODT.Data.Run方法可以简单地通过遍历对象树完成测试。只需要写一行调用的代码。
可以在对象树上通过CheckBox选中或不选某些元素来有选择地控制参与测试的元素。当然还可以通过使用Group.Run、Object.Run或ArrayObject.Run方法来指定对象树中的某部分元素进行测试。