IBM® Rational® Functional Tester 为测试人员提供了一个测试对象识别框架以及一个简单的用户界面,以执行基于
GUI 的测试脚本。但是,在有些条件下,例如测试一个基于 Eclipse 的程序,您可能会发现测试的 GUI
中全是二义性情形的测试对象。这些对象拥有几乎一样的属性,只有轻微的差异。很难直接指定目标对象属性的模式以及识别对象。识别的结果可能包含有多个二义性的类似对象,从而导致识别失败。本文向您介绍了怎样消除这些二义性的情况,并给出了一些指导以执行灵活且轻松的维护性测试脚本。
安装 IBM® Rational® Functional Tester V7 版本。
- 导入范例 Rational Functional Tester 项目(查看 下载)。您将会看到一个名为
BaseCase 的脚本以及一个名为 util
的文件夹。
- 通过选择 Window > Open Perspective > Java
来切换至 Java™ 视图。您将会看到以下的三个包:
- (default package)
- resources
- util
BaseCase 脚本位于默认的包中,其中还有它的辅助类 BaseCaseHelper
,以及与 Resources 包中脚本有关的其他配置文件。这两个包在 Functional Test 视图下看不到。您创建了
util 包,以及包中的类。在接下来的章节中,您将会使用到这个框架(见于图 1)。
图 1. Rational Functional Tester 项目的结构
建议您在 getMappedTestObject() 方法不能使用时,使用
find() 方法来找到一个测试对象。列表 1 中的代码显示了 find()
方法的结构。
列表 1. 找到方法结构
// Finds all candidates that match given search criteria starting at this TestObject
public TestObject[] find(Subitem properties);
|
find() 方法通过将测试对象的特定属性,与给定的标准相比较以找到一系列的候选对象。您可以通过代表属性的名字/值,或者包含有一个或者多个匹配字符串来搜索一个测试对象。如果使用默认的
getMappedTestObject() 方法不能识别一个测试对象,那么您可以首先定位它的父类,然后通过访问父类的
find() 方法来找到目标测试对象。显然,find()
方法提供了可观的便利。脚本不再取决于对象映射。搜索候选测试对象的结果是可预测的,因此也是可靠的。您可以通过对象的属性值来找到一个测试对象,这些属性值可能是一个简单的文本。维护脚本起来会更加容易。
但是,如果 getMappedTestObject() 方法不可行的话,find()
方法不会包含所有的事例。不会总有明显系列的属性值会匹配。find() 方法取决于明显系列的属性值。因此,如果测试对象没有这样一系列的属性,那么这种方法就不会正常地发挥其功能。但是我们可以在返回的数组中一个个地试一下测试对象,这并不是一个聪明的办法。有时,甚至很难找到测试对象可识别的父类,所以搜索必须从最顶层开始,例如从窗口开始。这就会降低测试对象的可识别性。
考虑一下 find() 以及 getMappedTestObject()
方法的缺陷,您需要另外一个方法来解决 Rational Functional Tester 对象识别中的二义性情形。在本文中,我们介绍了基于路径导航方法,来找到目标测试对象。我们将会使用程序
ClassicsJavaA 作为一个范例。为了让事情变得更加简单,我们假设 Place
Order 按钮就是要找的测试对象。
图 2. 范例程序的主窗口
在记录 Place Order 按钮的点击操作之后,您会得到图 3 中对象映射的以下层级结构。您可以看到
Place Order 按钮是框架的子部分。框架会作为主窗口来显示,而且它就是 Place Order
按钮的位置所在。当然,在本例中,您可以简单使用 find() 方法来定位按钮。但是,我们将会尝试另外一种方法来解决这个问题。
图 3. 对象映射的层级结构
对基于导航对象识别的介绍
有时测试人员会通过可见的线索来搜索测试的对象,例如关系中的相对位置。例如,您可能会通过它与文件夹封面图片的相对位置来找到
Place Order 按钮。与之类似,对于一个给定的测试对象,叫做锚对象,您可以使用 Rational
Functional Tester API 来找到带有给定路径的任何对象。再次使用上面的例子,您可以通过找到对象附近的位置、文件夹的图片以及特定路径来找到
Place Order 按钮。这里所谓的术语“路径”是指在对象映射中将一个对象节点移动到另一个上时的逻辑距离。
通过对象映射来进行导航
在 Private Test Object Map for Script BaseCase
窗口中,您知道 Place Order 按钮是主框架的子类。显然,该对象映射并 没有 包含主框架中所有的构件。按照以下步骤来得到对象映射树的大致轮廓:
- 点击 Test Object 然后在主窗口的菜单上点击 Insert Object(s)
以打开向导对话框。
- 使用 Object Finder 来强调主框架,然后选中它。
- 选择 Include all available objects on this window
然后点击 Finish 。
如图 4 所示,现在您可以看到添加至对象映射的主框架的更多子节点。
重点:
尽管您选择了“include all”选项,该选项并没有 包含主框架的所有子节点。该对象映射只能帮助您知道
Place Order 按钮的位置。
图 4. 对象影响更加具体的层级结构
您可以使用另外一种工具,来找到主框架的所有子节点。实际上,您刚刚已经使用了它。它就是 Insert
Object(s) 向导对话框(图 4)。使用这个向导,您就可以看到所有的 可映射对象。按照以下的步骤来定位
Place Order 按钮。
- 在主窗口中选择 Test Object >Insert Object(s)
以重新打开向导对话框(图 5)。
- 对于 Selection Method,选择 Test Object Browser
。
- 找到 Place Order 按钮,根据上面生成的测试对象映射给出的层级关系中的暗示进行操作。
图 5. 测试对象浏览器
根据 Test Object Browser,您可以在测试对象映射中看到许多的对象。对象浏览器中的对象的顺序,与测试对象映射中的顺序不同。但是,测试对象映射仅仅给了您一点暗示,以帮助您在对象浏览器中找到当前的对象。通过再一次按照前面介绍的步骤进行操作,您可以轻松找到文件夹的图形节点。然后您可以找到从图形节点到按钮节点的确切路径(见于图
6)。
图 6. 从图形到 Place Order 按钮的路径
如图 6 所示,从图形节点到按钮节点的路径如下所述。注意子类的索引在这里非常重要。
- 首先,将三个层次移动到父层次上。
- 然后移动主框架的 FIFTH 。
使用 API 来执行导航操作
现在您已经知道,怎样找到两个测试对象之间的路径。在本部分中,您将会学到怎样使用 API 来自动定位带有给定路径的目标测试对象。这项任务所需的
API 在列表 2 进行了总结。
列表 2. 定位测试对象所需的 API
/**
* This method returns an array of references to the object's mappable children.
* The references to the objects should be released by calling he unregister method.
* If the object has no mappable children, a 0-length array will be returned.
**/
TestObject[] testObject.getMappableChildren();
/**
* This method returns a reference to the parent object that appears in the object map.
* The references to the objects should be released by calling he unregister method.
**/
TestObject testObject.getMappableParent();
/**
* This method returns the topmost mappable parent object that appears in the object map.
* The references to the objects should be released by calling he unregister method.
**/
TestObject testObject.getTopMappableParent();
|
至于简单性,我们并不使用 unregister 方法来注销迭代的测试对象。ObjectFinder
类是含有所有导航操作的辅助类。图 7 中的 UML 显示了这些类之间的关系。注意出于稳定性考虑,TestObjectNotLocatedException
必须源自于 RuntimeException 。
图 7. 类与 UML 之间的关系
考虑一下路径范例,列表 3 向您展示了怎样书写代码以找到 Place Order 按钮:
列表 3. 找到 Place Order 按钮的对象
// This method is used to find the button Place Order
public GuiTestObject PlaceOrder() throws TestObjectNotLocatedException{
// The path we specified to find the button from the album image
// First move up 3 times, then move down to the fifth child
String pathString = "P3;C5";
Path path = null;
try{
path = new Path(pathString);
}catch(IllegalPathStringException illegalpath){
logError(illegalpath.getMessage());
}
// Assume that the imageAlbum() is already found
return new GuiTestObject(ObjectFinder.locateTestObject(imageAlbum(), path));
}
|
首先我们指定一个路径字符串,它描述了从图标到 Place Order 按钮的路径。然后我们使用
ObjectFinder 类来定位我们想要的目标测试对象。
我们已经看到了,怎样以各种方法来找到一个测试对象。我们可以使用默认的方法来找到测试对象。我们还可以使用
find() 方法来找到匹配属性/值的测试对象。而且我们可以定位带有给定对象及路径的测试对象。在本段中,我们将会讨论怎样选择正确的方法,以及怎样组织
Rational Functional Tester 对象的源代码。
选择合适的对象识别方法
显然,默认的方法拥有丰厚的工具支持。Rational Functional Tester 提供了强大的工具,例如
Test Object Map 和 Script Assure ,可以轻松解决脚本开发的复杂性问题,并降低开发所需的时间。但是,有一些脚本开发员所抱怨的正是简单性。他们认为工具隐藏了一些他们想要控制的细节。find()
方法是灵活和简单的。它使脚本开发员能够更强地控制测试脚本。这就是为什么在脚本开发中它得到广泛的应用,以替换默认方法的原因。基于导航对象识别方法非常有效和简单。有一点非常重要:它几乎可以在任何场所使用。但是,使用
UI 结构还是十分敏感的。
我们将会向您展示怎样使用 find() 方法,以及替代性的基于导航方法,同时享受使用工具所带来的便捷之处。
脚本组织的建议
回忆一下 Rational Functional Tester 对象结构的第一部分。我们知道所有的对象搜索方法默认条件下都是在辅助类中执行。例如,搜索
Place Order 按钮的默认方法如列表 4 所示。
列表 4. 默认的 Place Order 按钮代码
public abstract class BaseCaseHelper extends RationalTestScript {
/**
* PlaceOrder: with default state.
* .class : javax.swing.JButton
* accessibleContext.accessibleName : Place Order
* name : placeOrderButton2
* .classIndex : 0
*/
protected GuiTestObject placeOrder() {
return new GuiTestObject(getMappedTestObject("placeOrder"));
}
/**
* Schubert4_14Jpg: with default state.
* .class : javax.swing.JLabel
* iconDescription : Schubert4_14.jpg
* .classIndex : 2
*/
protected GuiTestObject schubert4_14Jpg() {
return new GuiTestObject(
getMappedTestObject("schubert4_14Jpg"));
}
}
|
然后您创建一个辅助类,该类扩展了默认的辅助类并超越了默认的方法。它如列表 5 中的代码所示。
列表 5. 创建辅助类的代码
public class BaseCaseUserHelper extends BaseCaseHelper {
// This method is used to find the button Place Order
public GuiTestObject PlaceOrder() throws TestObjectNotLocatedException{
// The path we specified to find the button from the album image
// First move up 3 times, then move down to the fifth child
String pathString = "P3;C5";
Path path = null;
try{
path = new Path(pathString);
}catch(IllegalPathStringException illegalpath){
logError(illegalpath.getMessage());
}
// schubert4_14Jpg() is object for the cover image
return new GuiTestObject(
ObjectFinder.locateTestObject(schubert4_14Jpg(), path));
}
}
|
最后,让脚本类扩展用户定义的类。通过这种方法,您不需要编辑任何已存在的对象搜索方法。您只是超越了它们,将已存在的对象搜索方法的最强部分结合起来。
描述 |
名字 |
大小 |
下载方法 |
示例脚本 |
RBAT_Impl.zip |
10KB |
|
学习
获得产品和技术
讨论
|