级别: 中级 杨 莉, 测试工程师, IBM 陈 昱旻, 测试工程师, IBM 祝 天光, 测试工程师, IBM
2009 年 3 月 27 日 本文首先介绍了 IBM Rational Functional Tester(RFT)提供的对 Windows 应用程序和 Windows Domain 的支持,然后用一系列的例子说明使用 RFT 开发针对测试 Windows 程序的脚本时会遇到的问题和利用 Domain 来作为解决方案。
概述
 | |
本系列从如何构建结构良好的测试框架、高效的对象缓存机制,以及测试 Windows 应用程序的技巧和方法等方面,介绍如何运用 RFT 测试 Windows/.NET 应用程序。
|
|
IBM Rational Functional Tester(RFT)是用来自动化测试 Java 和基于 Web 应用的工具。但是,RFT 是否能够良好的支持一直是讨论的热点话题。RFT7.0 目前可以支持录制和回放使用 Microsoft® Win32® 控件构建的应用程序。同时,RFT7.0 也支持 Microsoft .NET® Framework 2.0。
Rational Functional Tester 支持自动化测试的GUI控件包括Java™、.Net、HTML、Siebel、SAP、Ajax、Flex 和 Microsoft® Windows,支持这些控件所在的环境就称之为 Domain。一个 object domain 提供了一种类别对象的信息。比如,所有的 Java 对象都位于 Java Doamin 中。一般来讲,每个 HTML Browser 都有自己的 Domain 实例,每个 Java 虚拟机也是如此。RFT 为 Windows 和 .NET 的应用程序在需要或者请求时才动态创建 Domain 实例。DomainTestObject 类提供了获取这些 Domain 信息的方法。
本文首先介绍了 RFT 提供的对 Windows 应用程序和 Windows Domain 的支持,然后用一系列的例子说明使用 RFT 开发针对测试 Windows 程序的脚本时会遇到的问题和利用 Domain 来作为解决方案。
Rational Functional Tester 支持的 Windows Domain
关于 Windows Domain,RFT 支持录制和回访使用 .NET Framework 1.0/1.1 和 Win32 控件构造的用户程序。同时,也支持在 .Net Framework 2.0 的平台上测试这些控件。RFT7.0 版本还支持录制和测试包含 DataGridView、MaskedTextBox、ToolStrip、WebBrowser 和 SplitContainer .Net Framework 2.0 控件的应用程序。
除了位于 Win 或者 .NET Domain 中的对象外,下面的列表描述了一些 RFT 所支持的和 Windows 相关的嵌套 Domain:
HTML - Windows Owned -- 一些 IE 的通用对话框会显示为 Windows 的 Domain 对象。
VB.Net - Windows as owned -- VB.Net WinForms 应用程序上显示一些非 WinForm 的对话框。比如,一个 VB.Net 应用程序显示一个通用的对话框,如 File Open、Print 或者消息框。
Windows - HTML as child -- 这种情况是通用 Windows 应用程序(VB 6.0 或 MFC)使用嵌入的 IE 浏览器控件。
Windows - HTML as owned -- 这种情况是通用 Windows 应用程序(VB 6.0 或 MFC )使用嵌入的 IE 浏览器控件,这个控件显示由 HTML 组成的对话框(通过调用 JavaScript 的 ShowModalDialog)
利用 Domain 识别 Windows 控件
RFT 能够识别两种不同的 Win Domain 嵌套对象:Parent-Child 嵌套和 Owner-Owned 嵌套。Parent-Child 嵌套是一个对象被包含在另一个对象里,比如表格上的按钮。而 Owner-Owned 嵌套是 owned 对象有它自己的顶层窗口,比如一个对话框被一个顶层窗口 owned。以下图为例,点击 Options 按钮会弹出一个 Configuration 窗口,这个窗口就被 Login 窗口 owned。
图 1. Configuration 窗口
使用 RFT 所自带的 Object Map 来捕获这两个窗口:
图 2. RFT 所自带的 Object Map
从 Object Map 中可以看出这些 Objects 都是属于 Win Domain 的。每一个 Object 都列出了它的对象类型和 Domain 类别。例如对象 Win:Window: IBMECMLogin: WindowsForms10.Window.8.app.0.23976ef 是一个 WindowsForms10.Window.8.app.0 类型的对象,前缀 Win 表明对象位于 Win 测试 Domain 中。如上图所示,每个对象的测试 Domain 总是列在 Object 条目的最前端。除了这两个 window,每个 window 里的控件都是作为子节点被列在它们的父窗口中的。例如对象 Win:Window:WindowsForms10.BUTTON.app.0.23976ef 对应的是 Configuration 窗口上的 Cancel 按钮。在这个例子中,每个子节点都和它的 Parent 一样有同样的 Win Domain 前缀。如果一个子节点和它的 Parent 有不同的 Domain,在 Object Map 中会列出两个 Domain 前缀名。
Windows 和 .NET 应用程序的 Domain 实例是 RFT 在需要或者被请求的时候动态创建的。DomainTestObject 类提供了获取这些 Domain 信息的方法。getDomains() 方法返回一个 Domain 数组,RFT 能够识别 Windows 对象的前提条件是 Win 或者 .NET Domain 在返回的数组里。
对于一般且单一 Domain(Win 或者 .NET)的 Windows 对象,RFT 是通过“属性对”来识别这些它们的。比如,as “.class”,”.PushButton”;”.name”,”Login。一般来说,可以先获取 Windows 的 Domain,然后在 Domain 下查找这些对象。这样的方法比直接从 RootTestObject 开始查找要有效率得多,可以大量地减少由于查找而产生的测试等待时间。以下代码说明了这一过程:
String domainName = “Win”;
Object actualDomainName = null;
//获取所有得 Domains,并用 Domain 的名字匹配找到需要的 Domain
DomainTestObject domains[] = getDomains();
for (int j = 0; j < domains.length; j++)
{
actualDomainName = domains[j].getName();
if ((actualDomainName != null) && (actualDomainName.equals(domainName)))
{
for (int topObjects=0; topObjects<domains[j].getTopObjects().length; topObjects++)
{
// 返回一个在 Domain 里的顶层对象数组
TestObject top = domains[j].getTopObjects()[topObjects];
//使用顶层对象作为 Parent 来查找 Login 对话框
TestObject to = top.find(atDescendant
(“.class”,” WindowsForms10.Window.8.app.0”,”.name”,”IBMECMLogin”);
|
对于一些特殊情况,比如,对象位于不同的 Domain:.NET 控件位于 Windows 应用程序或者基于 Windows 的对话框出现在 Java 应用程序中,RFT 也许不能准确定位这些嵌套对象的 Domain。有时候,启动被测应用程序的时机也有可能会影响 getDomains() 的结果。为了解决以上情况,我们需要增加一些代码以保证 Win Domain 能准确的被获取到。
RootTestObject root = RootTestObject.getRootTestObject();
IWindow current = RationalTestScript.getScreen().getActiveWindow();
Long hWnd = null;
Integer pId = null;
hWnd = new Long(current.getHandle());
pId = new Integer(current.getPid());
//通过对Windows的handle和进程ID匹配来找到正确的窗口
if (hWnd != null)
{
testObj = root.find(atChild(".hwnd", hWnd, ".domain", "Win"));
domainObject = testObj[0].getDomain();
}
else if (pId != null)
{
testObj = root.find(atProperty(".processId", pId));
domainObject = testObj[0].getDomain();
}
|
如果一个激活窗口中的控件并不需要被识别或者操作,IWindow 是一个比较简单易用的接口。它可以访问窗体管理系统,并且轻松的完成诸如“关闭”等简单操作。
RootTestObject root = RootTestObject.getRootTestObject();
IWindow[] wins = root.getTopWindows();
int length = wins.length;
for (int i=0;i<length;i++)
{//用窗口的标题作为匹配对象查找需要的窗口
if(wins[i].getText()!=null &&
wins[i].getText().contains("expected window”))
{
wins[i].activate();
wins[i].close();
}
|
总结
本文向初学者介绍了 Rational Functional Tester 所支持的 Windows Domain。这些 Domain 可以用来组织和识别其下的对象。正确使用 Domain 可以更有效地查找测试对象,减少测试等待时间。
另外,开发针对 Windows 应用程序的测试脚本还需要诸如处理未预期的对话框以及开发有效率的查找方法来识别模糊控件将在这个序列的后续文章给予详细说明。
免责声明
本文包含解决方案。IBM 授予您(“被许可方”)使用这个解决方案的非专有的、版权免费的许可证。然而,解决方案是以“按现状”的基础提供的,不附有任何形式的(不论是明示的,还是默示的)保证,包括对适销性、适用于某特定用途或非侵权性的默示保证。IBM 及其许可方不对被许可方使用该软件所导致的任何损失负责。任何情况下,无论损失是如何发生的,也不管责任条款怎样,IBM 或其许可方都不对由使用该软件或不能使用该软件所引起的收入的减少、利润的损失或数据的丢失,或者直接的、间接的、特殊的、由此产生的、附带的损失或惩罚性的损失赔偿负责,即使 IBM 已经被明确告知此类损害的可能性,也是如此。
参考资料 学习
获得产品和技术
讨论
作者简介  | |  | 杨莉,2007 年加入 IBM,之前有三年 IT 领域功能和系统测试经验,现为 Filenet 产品测试工程师,主要使用 Rational Functional Tester 和 Rational Robot 进行自动化脚本开发。 |
 | |  | 陈昱旻,现为 IBM 中国开发中心负责 FileNet 功能测试的工程师。于 2000 年毕业于南京航空航天大学计算机系,获得硕士学位。有多年的数据库应用开发及测试经验,对自动化测试脚本开发有深厚兴趣。 |
 | |  | 祝天光,现为 IBM 中国开发中心负责 FileNet 功能测试的工程师。于 2001 年毕业于东北大学,获学士学位,有数年 Java 开发经验,及三年使用 Rational Robot 进行测试自动化的经验。现从事使用 RFT 进行更加稳定有效的测试自动化工作。 |
对本文的评价
|