内容


使用 Rational Functional Tester 的 getProperty 和 invoke 方法测试定制的 Java 控件

Comments

IBM® Rational® Functional Tester 提供了标准接口,便于操作标准 Java™ 控件。例如,在 Rational TextGuiTestObject 接口中,您可以很方便的使用getTextsetText 方法获取/设置Swing文本框。另一方面,任何GUI自动化工具都很难实现非标准的或定制控件的自动化,包括 Rational Functional Tester。 定制控件 并不存在于标准部件之中(例如,AWT 或 Swing),但它们是应用程序开发者不断积累所创造的。 Rational Functional Tester 开发者并不知道这些控件,不能预料到您所需要的方法,因而他们不可能提供包含所有方法的接口。为了测试这些接口,您需要直接从控件本身获取控件如何工作的信息。幸运的是, Rational Functional Tester为我们提供了一条途径,那就是使用 getPropertyinvoke方法。

Java applet 就是一个定制控件的实例,如图 1所示。 这是 Lotus Notes中包含的 Editor applet 。

图 1. Lotus Notes Editor applet
Lotus Notes Editor applet
Lotus Notes Editor applet

这个 applet 显示了用户输入富文本(可设置文本为粗体、斜体、文本颜色等等)的区域。用户通过使用顶部 applet 的按钮和列表框控制文本的显示。 这些按钮并不是标准控件。就是说,它们不属于 Swing 或 AWT 按钮,而属于 Lotus的开发者。它们的包和类名,com.lotus.app.MultiImageButton,表现出了这一点。很明显,这个包中的类不是一种标准控件,因此 Rational Functional Tester 不能提供包含您需要的一切接口。

但是,即使这些按钮不是标准控件,Rational Functional Tester 仍然可以使用最普遍的类来识别它们,即 GuiTestObject。但在大部分情况下,这样做还不能满足要求。问题在于,对比直接提供的 GuiTestObject 类,您需要更多有关控件的信息,更多操作它们的方法。例如,虽然 GuiTestObject提供了点击按钮的方法,但是它没有提供获取按钮名称(例如,用来区别粗体按钮和斜体按钮)的方法 getText ,而且它没有提供 isSelected 方法以确定是否某个特殊按钮已被选择。但这些正是彻底测试 applet 所必需的信息。因此,您不得不使用 Rational Functional Tester 的 getPropertyinvoke 方法直接从控件中获取信息。

本文为您展示了如何使用 Rational Functional Tester 测试定制的Java控件。本文中我们主要使用 Lotus 创建的 Editor applet 实例,但您可以将此原则应用于任何定制的 Java 类中,无论其是否嵌入 Web 页面内。

对象图(Object Map)

当您实现自动化 Editor applet 时,首先要做的就是映射它的对象。步骤如下:

  1. 创建一个 new script
  2. 打开 Object Map
  3. 选择 Insert Test Object
  4. 在页面中突出显示 control
  5. 选定 Include All Objects on Selected Page
  6. 点击 Finish

这步为 My Object Map 增加了页面中的所有对象,如 图 2所示。

图 2. 来自于 Editot applet 的对象图
Object Map
Object Map

注意:
由于在本例中您测试的是一个 applet,因此当您增加这些对象时不得不选择 Java 域。否则,将会只有一个对应 applet的对象,而不是许多个对应 applet 中 Java 控件的对象。如果您仅仅是测试单机 Java 应用程序,那么这些都是不必要的。

正如您所见的,Rational Functional Tester 能够辩识出 applet 中的任何控件都是独立的 GUI 对象。但是,定制的控件往往并不由 Rational Functional Tester 所能辩识为独立对象的控件组成。例如,Lotus Notes 具有另外一种称为 Action Bar 的包含许多 Action 按钮的 applet,如 图 3所示。

图 3. Action Bar applet
Action Bar applet
Action Bar applet

在映射过程中,这些 applet 仅仅产生一个单独的测试对象,如图 4所示。

图 4. Action Bar applet 的对象图
Object Map of the Action Bar applet
Object Map of the Action Bar applet

仅有一个单一测试对象的原因是 applet 中的按钮并不是真实的按钮,因为并没有独立的 GUI 对象。取而代之的是,Action Bar applet 在 Action Bar 上“绘制了”每个对象。Action Bar applet 追踪每个按钮的边界。当用户在 Action Bar 中点击时, applet 拦截此响应并指出用户点击了哪个按钮,给出它的边界。由于其具有此种特性,因而更适宜自动化,这就是为什么我在大部分文章中都关注更简单的 Editor applet 的原因。 但是,由于自绘制控件的问题具有普遍性,在文章的结尾我将回到 Action Bar applet,用它来展示如何使用 Rational invoke 方法作为替换一解决这个问题。

由于 Rational Functional Tester 能够辩识出 Editor 控件中的单个按钮,因此对它的测试变的非常容易。这些按钮在对象图中注册为 GUI 测试对象,并且分配了索引以对应于它们在 applet中的位置。因此,您可以与索引结合,使用 GuiTestObject 方法点击任何特殊按钮。例如,为了点击 Bold 按钮,您可以在对象图中找到索引为 1 的按钮,将此对象转移为脚本,然后调用点击方法。

但是,很可能通过特殊名称的查找而不依靠索引将获得更好的效果,例如开发者改变了这些按钮的顺序。但是这些信息并不能通过任何 GuiTestObject 方法(例如,在 GuiTestObject 中不存在提供按钮名称的 getText 方法)直接获得。 因此,您必须直接查询按钮以获取相关信息。 存在两种使用 Rational Functional Tester 的方式获取这部分信息:查询按钮的属性或调用一个方法。让我们先来举例说明第一个。

获取控件的属性

Rational Functional Tester 为您提供了一种获取特殊控件属性的方法:TestObjectgetProperty 方法。举个例子,如果您碰巧知道 Editor applet 按钮拥有一种被称为 toolTipText 的属性,它包含了按钮的名称,那么您可以使用下述代码获得这个名称。

列表 1:获取按钮属性
String buttonName=(String)multiImgButton().getProperty("toolTipText");

这部分代码调用 GuiTestObject multiImgButton 中的 getPropertygetProperty 方法返回 Object类的一个实例,因此您必须把结果转换成合适的类型,在本例中是 string 型。运行此代码后,buttonName 被设置为粗体,您可以通过名称辩识这个按钮。

正如您看到的,当知道所需要属性的名称时,您可以很容易的获得测试对象的属性。诀窍就是要知道属性的名称。您不可能猜到您所需要的属性名就是 toolTipText。因此,为了找出控件所提供的属性,您可以使用如下方法获取控件的所有属性并打印出它们:

列表 2:获取控件的所有属性
/**
 * Prints out all the properties of an object to the console
 * @param to	object whose properties you want to print
 */
public static void printProperties(TestObject to) {
Hashtable htable = to.getProperties();
int i = 1;
Enumeration eKeys = htable.keys();
Enumeration eElems = htable.elements();
while (eKeys.hasMoreElements()) {
System.out.println("Property " + i + ": name=" 
+ eKeys.nextElement() + "; value=" 
+ eElems.nextElement());
i++;
}
}

这种方法打印出测试对象(TestObject)的所有属性。它调用了测试对象的 getProperties 方法,并返回一个包含了控件所有属性及其对应值的哈希表。它仅仅是简单的打印出所有的数据。 您可以使用如下命令调用它,从对象传递 GuiTestObjectprintProperties(multiImgButton());

控制台窗口显示属性。如果您在 Editor applet 中传递一个按钮,您将得到如下输出:

列表 3:输出
Property 1: name=visible; value=true
Property 2: name=foreground; value=java.awt.Color
[r=0,g=0,b=0]
Property 3: name=ignoreRepaint; value=false
Property 4: name=minimumSizeSet; value=false
Property 5: name=focusTraversalKeysEnabled; value=true
Property 6: name=location; value=java.awt.Point[x=0,y=2]
Property 7: name=focusTraversable; value=true
Property 8: name=background; value=java.awt.Color[r=
255,g=255,b=255]
Property 9: name=name; value=canvas0
Property 10: name=selected; value=false
Property 11: name=backgroundSet; value=false
Property 12: name=toolTipText; value=Bold
Property 13: name=maximumSizeSet; value=false
Property 14: name=lightweight; value=false
Property 15: name=font; value=com.rational.test.ft.value.
FontInfo[name=Dialog,style=0,size=12]
Property 16: name=opaque; value=true
Property 17: name=mousePosition; value=java.awt.Point
[x=14,y=13]
Property 18: name=alignmentY; value=0.5
Property 19: name=alignmentX; value=0.5
Property 20: name=preferredSizeSet; value=false
Property 21: name=doubleBuffered; value=false
Property 22: name=maximumSize; value=java.awt.Dimension[width=32767,height=32767]
Property 23: name=focusOwner; value=false
Property 24: name=cursorSet; value=false
Property 25: name=preferredSize; value=java.awt.Dimension[width=27,height=27]
Property 26: name=foregroundSet; value=false
Property 27: name=focus; value=false
Property 28: name=locationOnScreen; value=
java.awt.Point[x=173,y=179]
Property 29: name=fontSet; value=false
Property 30: name=curImage; value=0
Property 31: name=size; value=java.awt.Dimension
[width=27,height=27]
Property 32: name=enabled; value=true
Property 33: name=y; value=2
Property 34: name=x; value=0
Property 35: name=bounds; value=java.awt.Rectangle[x=0,y=2,width=27,height=27]
Property 36: name=minimumSize; value=
java.awt.Dimension[width=27,height=27]
Property 37: name=valid; value=true
Property 38: name=width; value=27
Property 39: name=filtered; value=0
Property 40: name=showing; value=true
Property 41: name=displayable; value=true
Property 42: name=height; value=27
Property 43: name=focusable; value=true
Property 44: name=class; 
value=lotus.notes.apps.editorpanel.MultiImgButton

您需要仔细阅读列表,寻找可能满足您需求的属性。当发现您需要的属性时,您可以把其名称作为 getProperty 的输入参数,它将返回其属性值。

Editor applet 中另一个有用的按钮属性是 selected。它能告诉您某个按钮(如粗体按钮)是否已被选择,从而可以知道您输入的文本是否为粗体。 您可以从输出中发现,当前属性是 false,即输入的任何文本都不是粗体。但是为了在脚本中使用这个信息,您可以使用 getProperty 方法获取这个属性:

列表 4:获取 selected 属性
boolean isButtonSelected = 
((Boolean)multiImgButton().getProperty("selected")).booleanValue();

这与前述获得按钮名称的代码非常相似。但是,由于返回值是原始值而不是一个对象,因而增加了额外的复杂性。为了使得数据有用,您需要首先把返回值转换为 Boolean 对象,然后将其转变为原始 Boolean 值。 您必须使用来自于 getProperty 所输出的其他的原始值(如 int 型)。

正如您看到的,对象中存在许多对于测试 applet 非常有用的属性。但是,属性的作用仅此而已。Java 控件拥有更多的方法,而需要参数的方法不能是属性。一般来说,您想直接获取控件方法。Rational Functional Tester 为您提供了一种方法,那就是使用 TestObjectinvoke 方法。现在让我们来看看。

调用控件方法

您可以使用 Rational Functional Tester的 TestObject 接口的 invoke 方法去调用 Java 控件的任何方法。因为每个 Java 属性都具有 get-and-set 方法,因此您可以使用 invoke 实现与 getProperty 相同的功能。您将会看到,invoke 方法可以做的更多。

让我们应用 Editor applet 中的另一个控件,如图 5所示的 Color Canvas 下拉菜单。

图 5. Color Canvas 控件
Color Canvas control

如果您在控件中选择了颜色,Editor applet 中的文本会显示所选的颜色。为了测试 Editor applet,您需要在控件中获得并设置颜色。

虽然这个控件看起来像 Swing 或 AWT 组合框,但它并不是。它是由 Lotus 开发者创建的选择颜色的定制控件。由于它不是一个标准控件,Rational Functional Tester 并不知道如何使用它,因此您必须使用控件的方法实现自动化。

首先,您需要知道控件拥有哪些方法。您可以查看源代码或使用 Java™ Reflection™ 找到它,您还可以使用 Rational Functional Tester 获得信息。方法如下:

列表 5: 获得控件的所有方法
/**
 * Prints out the methods of an object (omitting methods from java.lang.Object)
 * @param to	object whose methods you want to print
 */	
public static void printMethods(TestObject to) {
MethodInfo[] m = to.getMethods();
for (int i = 0; i < m.length; ++i) {
System.out.println("Method " + i + ": name=" + 
m[i].getName() + "; signature=" + m[i].getSignature());
}
}

这种方法可以获取控件的所有方法并在控制台显示它们。它使用 TestObject 中的 getMethods 方法返回一个 MethodInfo 对象数组。 然后遍历所有成员,显示它们的方法名称。

您可以像之前使用 printProperties 方法一样调用它,将由 Rational Functional Tester 的对象图(本例中称为 colorCanvas)返回的 GuiTestObject 传递进来,就像这样:

列表 6: 调用 printMethods
printMethods(colorCanvas());

这种方法显示了您可以使用的控件中的所有方法。

当我运行这段代码时,它显示了 307 种方法!不仅包含了类中定义的所有方法,还包括了其继承类的所有方法。其中的许多内容与您所需要的并不相关,但是显示在顶部的两种方法正是您所需要的:

方法 1: name=getColor; signature=()Ljava/awt/Color;

方法 2:name=setColor; signature=(Ljava/awt/Color;)V

如果您想获取、设置控件的颜色,您必须使用 invoke 方法调用本控件的这两种方法。很明显您需要知道您想调用的方法的名称以使用 invoke 方法, 您还需要知道这个方法所必需的参数和返回值。因此需要知道方法的签名。

签名以 JNI(Java™ Native Interface)格式显示。 参数类型列于圆括号中,在最后列出了返回值的类型。表格 1 来自于 Java 文档,用来解释被用于 invoke 方法的类型符号。

表格 1. 方法签名的 JNI 格式
CodeType
Zboolean
Bbyte
Cchar
Sshort
Zboolean
Iint
Jlong
Zboolean
Ffloat
Ddouble
Vvoid
L fully-qualitied-class;;例如:Ljava.lang.String;

第一个相关的方法,getColor,具有 ()Ljava/awt/Color; 签名。圆括号内是空的,表示了这种方法不包含任何参数。它返回一个 java.awt.Color 类型的对象。正如 L 所表示的那样,分号表示对象名的结束。第二种方法 setColor 具有 (Ljava/awt/Color;)V 签名。它具有 java.awt.Color 类型的参数,用来设置控件颜色。但正如 V所示(表示void),它不返回任何值。

invoke 方法已被重载。根据是否给调用函数传递参数的不同,它具有两种形式。由于不包含参数的调用形式比较简单,因此我们从它开始。

为了使用 invoke 方法的第一种形式,您需要做的仅仅是为 invoke 方法传递需要的方法名称。以下代码使用 ColorCanvasgetColor 方法,不包含任何参数:

列表 7: 通知 invoke 您要调用的方法名
java.awt.Color color = (java.awt.Color)colorCanvas().invoke("getColor");

getColor 返回一个 java.awt.Color 对象。确保将其存储在变量中,因为那是您获得的信息。但是 invoke 方法(例如getProperty)返回一个 Object 类的对象。为了使用它,您需要将其转变为 java.awt.Color 对象。

注意:
正如您看到的,invoke 调用与 getProperty 调用十分相似。如果您认为 Java 对象的所有属性都具有 get-and-set 方法,那一点也不奇怪。事实上,本例中颜色是 ColorCanvas 控件的一种属性,因此您可以使用 getProperty 方法获取相同的信息。

相比较获取颜色,设置颜色就变得有点复杂。因为 setColor 需要一个参数,您将不得不使用 invoke 的第二种重载形式,需要传递三个参数:

  • 您要调用的方法名称
  • 以 JNI 语法表示方法签名的字符串
  • 一组包含需要传递的实际参数值的对象

为了从 Rational Functional Tester 中调用 ColorCanvassetColor 方法,您首先要做的就是要决定为 setColor 传递哪些参数。本例中,它只需要一个参数:设置文本的颜色。为了调用这个方法,您需要创建一个颜色对象,并传递给控件。但是 invoke 方法需要您把这种对象存入一个对象数组中,因为任何特殊方法都可能具有多个传递参数。因此,您需要将参数存入数组,然后将其传入 invoke 方法:

列表 8: 将方法存入数组
Object [] color = {java.awt.Color.red};
  colorCanvas().invoke("setColor", 
  "(Ljava.awt.Color;)V", 
  color);

您能够用上述方法使用 invoke,任意设置 Editor applet 的文本颜色。

虽然从技术角度 invoke 方法的使用效果很好,但仍然有一个问题:您使用了用户不能实现的方式操纵 GUI,但 GUI 自动化的关键点就是确保 GUI 如用户使用一样工作。所以这个例子并不现实,尤其当您试图测试 ColorCanvas控件自身的 GUI,而不仅仅是 applet 的文本。所以最好写入复杂些的代码并点击控件从结果显示中获取颜色。在下一部分,您将看到使用 invoke 后更复杂更现实的实例,它展示了当试图操纵 Java 控件。

一个更复杂的案例

接下来让我们再看一个更复杂的例子 —— Action Button applet。这个例子的好处不仅在于展示了如何操纵一个 Rational Functional Tester 所不知道的控件,而且证明了如何获取并使用坐标操纵控件。这些都是测试定制控件时经常需要做的。

图 6 展示 Action Button applet 的形态

图 6. Action Bar applet
The Action Bar applet again
The Action Bar applet again

Rational Functional Tester 将此控件看作一个矩形。回想一下它被映射的时候,它返回一个控件,如图 7所示。

图 7. Action Bar applet 的对象图
The Object Map for the Action Bar applet again
The Object Map for the Action Bar applet again

Rational Functional Tester 不能区分控件所显示的按钮。因此,您不能像 Editor applet 一样简单的使用来自对象图的返回对象以点击某个按钮。

但为了自动化的点击这些按钮,您需要得到它们的坐标 。然后您才能使用这些坐标告诉 Rational Functional Tester 在按钮中点击某一点。您可以固定编码按钮的坐标,但将会是不可靠的,因为尺寸大小会根据文本变化。 最可靠的获取坐标的方法是使用控件自身的方法决定每个按钮的大小。您可以使用 Rational Functional Tester 的 invoke 方法实现。

首先您要知道控件中的哪些方法可以帮助您解决问题。例如,我运行了 printMethods 方法(来自于上一节),并且发现其中一种方法可以获得某个按钮的宽度。以下是其所显示的内容:

列表 9: 找出您可以使用的控件方法
Method 17: name=calculateButtonWidth; signature=(I)I

您可以使用 calculateButtonWidth 方法设置按钮的 X 坐标,方法是增加所有早先按钮的宽度。例如, Email 的 Send 按钮的 X 坐标等于 Save Document 按钮加 Close Document 按钮的宽度之和。您可以通过如下代码获得 Email 的 Send 按钮的 X 坐标:

列表 10: 获得 Email 的 Send 按钮的坐标
int iButtonIndex = 2;
for (int i = 0; i < iButtonIndex; i++) {
x += ((Integer)actionBar().invoke
("calculateButtonWidth", "(I)I", new Object[] 
{new Integer(i)})).intValue();
}

此外,还可以获取 applet 高度的方法获得按钮的高度。然后就可以计算出某个按钮的点击位置。下面是在 Action Bar applet 中普遍使用的可以点击任何按钮的方法。

列表 11: 在 Action Bar applet 中点击任何按钮的方法
public void clickActionBarappletButton(int iButtonIndex, GuiTestObject actionBar) {
int x = 0, y = 0, width = 0, height = 0;
	
// **** CALCULATE x coordinate  ****
for (int i = 0; i < iButtonIndex; i++) {
x += ((Integer)actionBar.invoke("calculateButtonWidth", "(I)I", 
new Object[] {new Integer(i)})).intValue();
}

// **** CALCULATE width  ****
width = ((Integer)actionBar.invoke
("calculateButtonWidth", "(I)I", new Object[] {new Integer(iButtonIndex)})).intValue();

// **** CALCULATE y coordinate ****
y = 0;
		
// **** CALCULATE height ****
height = (int)actionBar.getScreenRectangle().getHeight();

Point pointToClick=new Point(x + width/2, y + height/2);
actionBar.click(pointToClick);
}

这种方法计算出按钮中心相对于 actionBar 控件的位置,然后点击此点。

我们需要记住这种计算定制控件中所点击的坐标的方法。您会发现很多情况下,对象图中定制 Java 控件并不是可用的。在这种情况下,您能找到控件自身的方法,用它计算出组件的位置。将其作为一种简单算法告诉 Rational Functional Tester 需要点击的位置坐标。

注意:
有时候,Rational Functional Tester 并没有列出所有识别出的组件。这种情况下,您可以通过搜索控件(这些控件使用 Rational Functional Tester 的 getChildrenfind方法找到)的派生找到这些组件。事实上,Action Bar applet 比我之前所介绍的复杂的多,因为它由各种各样与对立按钮不匹配的组件面板组成。父类 applet 的派生包含所有按钮,并能辨别出用户点击面板时是哪个按钮被点击了。因此,实际上您必须调用 Action Bar applet 的子类的子类invoke 方法(而不是 Action Bar applet 本身)计算按钮的宽度。我为了表述的更清楚而简化了先前的例子,但是您应记住可以搜索定制 Java 控件的派生找到没有列出的组件,这些组件也许会提供您所需要的其他的方法和属性。

正如您在本例中看到的那样,自动化的定制控件可以变的非常复杂。有时候,控件的方法可以准确的满足您的需要。有时候不是。这时,您需要通过来自控件的数据创建相应的信息。

将所有组件放入小窗口类

现在您已经创建了操纵定制控件的代码,您需要将它放入脚本编辑器。很明显,您不希望在每个脚本中为了点击按钮全部重复创建复杂的代码。您更希望这段代码可以被任何脚本都可以使用的核心类的方法所调用。尤其是,您需要为这些控件创建小窗口类(widget classes)(请浏览在 参考资料中名为“Wrapping calls to the Rational Functional Tester API”的 developerWorks 文章)。您可以通过这种方式对用户隐藏细节部分,从而减少自动化过程中的错误。

您现在可以把 Action Bar 中点击按钮的方法移到 Action Bar 小窗口中了:

列表 12: 将方法移至小窗口(widget)类
public class ActionBarapplet {

private GuiTestObject actionBar=null;

public ActionBarapplet(GuiTestObject gto) {
actionBar = gto;
}

public void clickButton(int iButtonIndex) {
int x = 0, y = 0, width = 0, height = 0;

// **** CALCULATE x coordinate  ****
for (int i = 0; i < iButtonIndex; i++) {
x += ((Integer)actionBar.getChildren()[0].getChildren
()[0].invoke("calculateButtonWidth", "(I)I", new 
Object[] {new Integer(i)})).intValue();
}

// **** CALCULATE width  ****
width = ((Integer)actionBar.getChildren()[0].getChildren
()[0].invoke("calculateButtonWidth", "(I)I", 
new Object[] {new Integer(iButtonIndex)})).intValue();

// **** CALCULATE y coordinate ****
y = 0;

// **** CALCULATE height ****
height = (int)actionBar.getScreenRectangle().getHeight();

Point pointToClick=new Point(x + width/2, y + height/2);
actionBar.click(pointToClick);
}

在这个类中,您的用户可以使用返回来自于对象图的 GuiTestObject 构建一个 Action Bar applet,然后可以使用 clickButton 方法很容易的通知 Rational Functional Tester 点击按钮。当然,您会想给这个类增加更多的方法,包括 getNumberOfButtonsgetButtonName。在加入这些方法后,您还可以为用户增加出错校验和其他方便的工具(例如,重载 clickButton,使得用户可以以字符串方式输入按钮名称而不用依靠索引)。

以下是 Editor applet 类的开头,它包括了您之前创建的代码:

列表 13: Editor applet 类的开头代码
public class Editorapplet {

private GuiTestObject editor;

public Editorapplet(GuiTestObject to) {
editor=to;
}

public void typeKeys (String s) {
getCRTEditor().click();
RationalTestScript.getScreen().inputKeys(s);
}
public boolean isBold() {
return ((Boolean)getBoldButton().invoke
("getSelected")).booleanValue();
}

public void setBold() {
if (!isBold())
this.getBoldButton().click();
}
public void unsetBold() {
if (isBold())
this.getBoldButton().click();
}

public java.awt.Color getColor() {
return (java.awt.Color)getColorSelector().invoke("getColor");
}

public void setColor(java.awt.Color color) {
getColorSelector().invoke("setColor", 
"(Ljava.awt.Color;)V", new Object[] {color});
}

public GuiTestObject getCRTEditor() {
return (GuiTestObject)editor.find(SubitemFactory.atDescendant
(".class","lotus.notes.apps.editor.CRTEdit"))[0];
}

public GuiTestObject getBoldButton() {
//Bold is first button:
//0.2.0.0  = lotus.notes.apps.editorpanel.MultiImgButton
return (GuiTestObject)editor.getChildren()[0].getChildren()
[2].getChildren()[0].getChildren()[0];
}

public TestObject getColorSelector() {
return (GuiTestObject)editor.find(SubitemFactory.atDescendant
("class","ColorCanvas"))[0];
}
}

注意:
事实上您没有在本类中映射任何东西。相反的,用户传入一个 GuiTestObject 类以响应 applet 最顶部的 Java 类,而您可以动态的搜索所有的组件。 这使得 Editor applet 更通用化。

脚本可按照如下代码使用小窗口类:

列表 14: 脚本所使用的小窗口代码
TestObject to = Editorapplet(); //get the TestObject from the Object Map
Editorapplet editor = new Editorapplet(to); //construct the widget

editor.setBold();
editor.setColor(java.awt.Color.RED);
		
editor.typeKeys("testing");
System.out.println(editor.isBold());

正如您所看到的,它极大的简化了使用这些定制控件的方法。当然,正像我已提到过的,小窗口中存在很多种方法都是用户所需的。使用 invokegetProperty 方法,您可以为他们提供其所需信息。

使用这些方法的最佳实践

定制控件使人感到害怕,但是 Rational Functional Tester 为您提供了有力的工具。getPropertyinvoke 方法一般情况下足以满足处理 Java 定制控件所遇到的问题。您可以使用 getProperty 获取大部分您所需的信息,但是如果您所需的信息不是一种属性或者需要调用的方法需要一个参数,您可以使用 invoke 方法作为替代。

getPropertyinvoke 很相似,因为它们都允许您调用控件自身的方法,而不是使用由 Rational 软件提供的中间件接口。这使您可以更好的测试定制控件。但请不要错误的使用。 最好的方法就是使用这些方法获取关于控件的信息,依据这些信息决定如何告诉 Rational Functional Tester 按照用户需要操纵控件。换句话说,就是要避免使用 Java 控件或用户不能实现的操纵控件的方法集。如果您遵守这个规则,那么您的测试将会获得更好更全面的效果。

当自动化测试大型Java应用程序时,您一定会遇到定制控件。使用 Rational Functional Tester 的 getPropertyinvoke 方法,能够相对直接的创建您自己的调用以操纵这些控件。在您把这些调用封装入一个小窗口后,脚本编辑器可以像测试标准Java控件一样使用这些控件编写自动化脚本。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=227756
ArticleTitle=使用 Rational Functional Tester 的 getProperty 和 invoke 方法测试定制的 Java 控件
publish-date=05312007