RFT的对象识别技术

来源:互联网 发布:类似爱情只有我知 编辑:程序博客网 时间:2024/05/16 08:57


虽然目前在Watir的对象识别中(基于IEdev与Autoit)基本没有碰到识别问题,但该文章的介绍还是收获颇多,推荐!

http://www.ibm.com/developerworks/cn/rational/r-cn-extendsrftobj/

2008 年 2 月 28 日

长期困扰 Rational Functional Tester (RFT) 自动化测试的一个问题就是如何有效地识别 GUI 元素,以适应 GUI 的不断变化,这在敏捷开发日益成为主流开发模式的情况下显得更加重要。本文通过大量的实例向您介绍了针对不同的 GUI 元素,选择不同的对象识别技术,以提高 RFT 自动化测试的效率。

RFT 对象概述

RFT 对象

从开发的角度看,GUI 通常都是基于某一 GUI 开发库(SWT/SWING/AWT),这些库通常是按照面向对象的方式进行建模的,它将每一个 GUI 元素映射成该库中某一个类的对象。

从测试的角度看,所有的 GUI 元素,无论基于何种 GUI 库,都被 RFT 映射成对象,RFT 提供一个对象模型框架管理各种 GUI 元素。

图 1 是一个典型的基于 SWT 开发的 GUI,对于其中的一个按钮,在开发者看来,它就是 SWT 库中 Button类的一个对象;但是 RFT 并不区分这是 SWT 库中的按钮,或者是其他 GUI 库的按钮,它都被映射成 RFT 对象模型中GuiTestObject 对象。

在用 RFT 提供的 Inspector 工具获取 GUI 元素时,需要用到开发模型。而进行 RFT 脚本开发时,又需要用到 RFT 对象模型。熟练掌握两种对象模型,对提高 RFT 自动化测试效率非常有帮助。


图 1. RFT 对象模型示例
RFT 对象模型示例

RFT 对象识别

基于 RFT 的自动化测试,都会采用 IBM 推荐的 ITCL 框架。在这个框架下,所有的脚本被划分为三个层次:对象层,任务层,用例层。对象识别就是在 RFT 的对象模型框架下,得到被测程序的 GUI 对象。它是对象层开发中最核心的任务。

常用的 RFT 的对象识别技术可以分为两大类:静态识别与动态识别。动态和静态方法各有优缺点,静态方法识别效率高、开发成本比较低,但是脚本的可维护性比较差;而动态方法刚好相反。





回页首

扩展 RFT 对象识别技术

采用常用的对象识别技术,可以识别出大部分的 GUI 元素,但有时也会遇到 RFT 无法识别的 GUI 元素,事实上识别这类用常用对象识别技术无法识别的 GUI 元素占用了 RFT 脚本开发的大部分时间。

RFT 中一个非常重要的根接口是 IGraphical 接口,它定义了针对 GUI元素的所有标准操作(click,doubleclick,drag 等)。另外一个非常重要的根类是 GuiTestObject,它继承自TestObject 并实现了 IGraphical 接口。常用对象识别技术中 GUI 元素都是被映射为 GuiTestObject对象。它们在 RFT 对象模型中的位置如图 2 所示。灵活运用这些类、接口及其方法,能够极大地扩展 RFT 对象识别的功能。


图 2. RFT 对象模型类图
RFT 对象模型类图
  • 问题描述

使用 RFT 经常听到的一个谬论就是 RFT 只能测试基于 java 的 GUI 程序,对于 C/C++ 或者 windows 标准控件,RFT 无法识别。事实上,RFT 提供了 IWindow 接口用于识别平台相关的控件。

  • IWindow 接口介绍

从图 2 中可以看出,IWindow 接口也继承自 IGraphical 接口,从这点看,IWindow 接口具有与 GuiTestObject 类似的功能。

使用 IWindow 接口能够识别平台相关的 GUI 控件,但是其接口函数的具体实现与平台相关,windows 与 linux 上的实现就不一样,可以通过下述方法判断具体的平台,本文将主要分析 windows 上的应用。


清单 1
清单 1
  • 典型应用

图 3 是记事本的“页面设置”对话框,是一个 windows 原始窗体。如何识别这个窗体,并点击“确定”按钮呢?基于 RFT 的实现方法如下:


图 3. 被测试程序 GUI
被测试程序 GUI

确定对象识别的起始点。通常选取最上层窗体作为对象识别的起始点,具体方法如下所示:


清单 2
清单 2

这些方法都返回一个 IWindow 接口的数组,每一个数组元素代表一个顶层窗口,并且这些窗口之间是互相独立的。

识别符合要求的顶层窗口,即“页面设置”对话框。IWindow 接口提供了两个方法:getText() 与getWindowClassName() 来实现。对于窗体,getText() 返回窗体的标题;对于控件,getText()返回控件的文本。getWindowClassName() 返回 win32 标准控件名。如何知道被测程序的标准控件名呢?在 windows上有许多工具,例如下文中将提到的 AutoIt 以及 Visual Studio 提供的 Spy++。图 4 是用 AutoIt 得到的GUI 元素的属性。


图 4. 利用 AutoIt 得到 GUI 元素的属性
利用 AutoIt 得到 GUI 元素的属性

对顶层窗体数组根据文本值和标准控件名进行匹配,则可以识别出符合要求的顶层窗体。这两个方法均返回字符串,为了提高识别的效率,通常对这些字符串进行正则表达式匹配。具体用法如下,参数 sCaption 表示窗体的标题,sWindowClassName 表示窗体的 Win32 标准类名。


清单 3
清单 3

识别窗体内的控件,即“确定”按钮。以顶层窗口为起点,通过 IWindow 提供的 getChildren()函数可以得到内嵌在顶层窗体的 GUI 控件(如 button,label 等),该方法返回 IWindow接口的数组,对数组元素根据文本值和标准控件名进行匹配,即可识别出内嵌的控件。识别内嵌控件的方法如下,参数 iTopwin表示顶层窗体,sCtrlText 表示控件的文本值,sCtrlClassName 表示控件的 Win32 标准类名。


清单 4
清单 4

IWindow 还提供了 getOwned() 方法,可以得到出顶层窗体拥有的子窗体(如模式对话框等)。

完成点击“页面设置”窗体中“确定”按钮的 RFT 脚本如下。


清单 5
清单 5
  • 问题描述

在进行 GUI 自动化测试时,一个经常遇到的问题就是如何测试开发者定制的控件?通常一组定制的控件,是作为一个整体被 RFT识别出来,你可以对这个整体作一些操作,但是如何识别出每一个具体的定制控件呢?可以使用 TestObject 类提供的方法:Invoke 函数。

  • Invoke 方法介绍

Invoke 方法类似于 java 中的反射机制,它可以在运行时而不是编译时调用函数。通俗地说,在 RFT中,它可以根据字符串来调用相应的函数。这使得不仅可以调用某些确定的方法(如 GuiTestObject的方法),还可以主动查询定制控件本身提供的方法,大大加强了对象识别能力。

  • 典型应用

使用 Invoke 函数的一个典型例子就是测试 Notes 8 的 tab 项。Notes 8 的 tab 项是一个定制的 java控件。RFT 会将多个 tab 项识别为一个 GuiTestObject 对象,如何识别出每一个 tab 项呢?并执行关闭 tab 项的操作呢?

首先采用 Object map 方法识别出 RFT 能够识别出的最小的定制控件的集合。如下图 2 红色方框所示的 GUI 元素是 RFT 所能识别出的最小的对象。在本例中它被识别为 GuiTestObject 的对象:sTabFolderObject。


图 5. Notes 8 中定制控件
Notes 8 中定制控件

图 5 Notes 8 中定制控件

确定需要调用的方法。调用 Invoke 方法需要事先知道方法的名称,TestObject 提供了另外一个方法:getMethods 它能够返回控件所有的方法,你可以按照如下的方式调用它。


清单 6
清单 6

按照这种方式,能够在控制台打印该控件所有可用的方法,从中分析出需要的方法。在本例中发现 getItems 能够返回所有的 tab 项。

调用 Invoke 方法识别出具体的定制控件。完整的用法如下所示,参数 name 表示希望识别的 tab 项的文本值,sTabFolderObject 为上述红色方框表示的对象。


清单 7
清单 7

完成关闭 tab 项操作。利用 Invoke 可以很便捷的操作 GUI对象,但是一定要避免使用用户所不能操作的方式来操作控件,因为这违背了测试的原则。从 getMethods 返回的方法中发现 dispose方法也可以关闭 tab 项,但很显然用户不能这样操作,而用户关闭 tab 项的操作就是点击 tab 项的“X”。因此在 RFT脚本中,可以首先得到“X”的坐标,然后在该点执行单击操作。具体的方法如下所示。


清单 8
清单 8




回页首

集成第三方自动化工具

  • 问题描述

使用 RFT 进行自动化测试时,经常遇到这样的尴尬,一方面 RFT在识别某些对象时遇到一些问题,比如无法识别,识别效率低,开发识别脚本代价很高。另一方面又有大量的第三方 GUI自动化工具对某些特定的领域有很好的性能。如果能够结合 RFT 与其他自动化工具,就能够极大地提高自动化测试的效率,更加适应敏捷开发与测试。

  • AutoIt 介绍

AutoIt 是一种在 windows 平台上,针对 C/C++ 以及 windows标准控件的,免费、开源的自动化管理工具。AutoIt 本身有一种非常简单的脚本语言,这种脚本语言类于Basic,并且其脚本可以直接转化为可执行程序且不依赖于任何库。事实上,AutoIt 的这些功能,RFT 提供的 IWindow接口也能够完成,但 AutoIt 具有更高的效率。

  • 典型应用一

仍然以 IWindow 接口中点击“页面设置”对话框中的“确定”按钮为例。介绍如何结合 RFT 与 AutoIt 完成上述操作。

  1. 开发 AutoIt 脚本。AutoIt 对 GUI 对象的识别区分 windows 和controls。对于 windows 是通过 title/text 方式进行对象识别;对于 controls 是通过title/text/controlID 方式进行识别。ControlID 是 AutoIt 中特有的概念,它不是一个特定的值,可以是:内部ID,text,class,instance,classmn以及它们的组合。在本例中,最终需要识别的对象是“确定”按钮,同时它又位于“页面设置”窗体中。具体的 AutoIt 脚本如下。

清单 9
清单 9
  1. 在 RFT 中调用 AutoIt 脚本。RFT 提供了多种启动其它进程的方法,其中类RationalTestScript 提供的 startApp 和 Run 方法比较常用。使用 startApp 需要事先在 IDE中进行配置,而 Run 方法具有更多的普遍性,具体的调用方法如下。

清单 10
清单 10
  • 典型应用二

在 RFT 中一类经常遇到的问题就是如何处理那些非预期的活动窗体。例如,点击安全网页上的 link,而这个 link所指向的却是一个非安全的网页,如果浏览器对安全性要求较高的话,就会弹出一个对话框询问你是否仍然打开这个页面,如果选择“是”则下次重复这样的操作将不再会弹出对话框进行询问,否则下次仍然会询问。因此是否会出现这个窗体取决于是否建立了信任关系,而在脚本开发时是无法预见的。

采用常用的对象识别技术,其典型的处理方法如下所示。


清单 11
清单 11

上述处理方法采用了常用的对象识别技术识别那些非预期的窗体,如果这些窗体无法用常用方法识别,如何来处理这类问题呢?


图 6. 非预期的对话框
非预期的对话框

图 6 是打开网页前,系统弹出的一个对话框,它是一个 windows 原始窗体,无法采用常用方法识别(当然可以用 IWindow 来识别),以下结合 RFT 和 AutoIt 来处理。

  1. 开发 AutoIt 脚本。AutoIt 脚本的任务是点击“Security Alert”对话框中的“Yes”按钮。这可以分为两步,第一步判断对话框是否已经存在;第二步点击“Yes”按钮。具体的 AutoIt 脚本如下所示。

清单 12
清单 12
  1. 开发 RFT 脚本。RFT 脚本有三个任务,第一是点击安全网页上的 link 使得“Security Alert”对话框出现。第二是调用 AutoIt 脚本关闭弹出的对话框。第三是判断非安全网页是否已经打开。具体的 RFT 脚本如下所示。

清单 13
清单 13

从以上可以看出,相比单纯使用 RFT,基于 RFT 与 AutoIt 的混合解决方案需要的脚本显著减少,大大提高了脚本开发效率。当然这种混合解决方案需要你对 AutoIt 有一定的了解,增加了学习的负担,但是一旦掌握,对于提高自动化测试效率是很明显的。





回页首

总结

本文阐述了各种不同的对象识别技术,其中 IWindow 接口用于识别 windows 标准控件;Invoke 方法用于识别应用程序定制的GUI 控件;此外还介绍了 windows 平台上一款优秀的自动化工具 AutoIt 以及如何与 RFT 结合进行自动化测试。将 RFT常用的对象识别技术与这些特定条件下的对象识别技术相结合,能够使得 GUI 自动化测试更加敏捷。

原创粉丝点击