首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

谈 Dojo 应用的 UI 自动化测试(2)

谈 Dojo 应用的 UI 自动化测试(2)

Dojo 应用 UI 自动化测试框架挑选(设计)原则讲解完了所有的挑战,让我们来看看当我们要设计或者选取一个 Dojo 应用 UI 自动化测试框架时需要考虑的因素和原则。
概括起来,主要有以下八大原则。括号内是该原则所对应解决的挑战。
  • 隐式等待(A)
  • 位置关系操作(B,E)
  • 封装 Dojo 小部件 (C,D,F)
  • IBM 框架 (E)
  • 代码生成(D)
  • 测试数据的管理(D)
  • 录制与编码 (D)
接下来,我们一一来讲解每一条原则。为了帮助读者理解,讲解过程中会引用内部自行开发的 Dojo 应用 UI 自动化测试框架 Water Bear 的部分内容。
隐式等待挑战 A 提到了异步请求处理的问题也描述了几种解决方案,但都不甚理想。最理想的情况是自动化测试框架能够自己处理异步请求的问题,并且不需要开发者编写任何代码。这就是所谓的“隐式等待”机制。
目前,不少 Web UI 自动化测试框架都具备“隐式等待”功能,比如 Sahi 和 Selenium。Water Bear 使用的是 Sahi。当然,Sahi 同时也提供了对“硬编码等待时间”和“基于条件的等待”的 API 支持(因为,有些情况下还是不得不使用“硬编码等待时间”或“基于条件的等待”)。根据经验,超过 90%的情形是 Sahi 的“隐式等待”功能可以覆盖的,但是像“进度条”这样的功能就不得不用“基于条件的等待”。在进度条达到 100%之前,前端代码不断地向后台发起 Ajax 请求轮询进度状态。这种情形,Sahi 无法智能地得知哪一个 Ajax 请求的返回是“最后一个”,因此,就无法决定何时可以执行下一个动作。
清单 1. “进度条”代码示例
1
2
3
4
5
6
BrowserCondition cond = new BrowserCondition(getBrowser()) {
    public boolean test() throws ExecutionException {
        return getBrowser().isVisible(getBrowser().div("100%").in(es));
    }
};
getBrowser().waitFor(cond, waitTime);




清单 1 展示了 Water Bear 中部分实现进度条功能的代码,也就是 Sahi“基于条件的等待”的代码。在 test 方法返回“真”之前(也就是代码发现文本“100%”出现了),waitFor 方法一直处于轮询状态。waitTime 是一个超时时间。如果这个时间达到了,即便 test 方法仍然返回“假”,waitFor 还是返回。通常,这时已经可以认定 Web UI 的功能执行出现了问题。
只所以把“隐式等待”放在第一个来讲,是因为 Web UI 自动化测试框架是否具备该功能对于 Dojo 应用 UI 自动化测试实施成败是至关重要的。
位置关系操作Dojo 应用 UI 自动化测试框架应当具备根据给定对象定位其他对象的功能。这种相对的位置关系通常包括:在里面、在附近、在左面(右面)以及在上面(下面)等等。目前,Sahi 支持所有这些位置关系查找,另外还支持“在上面或者下面”以及“在左面或者右面”。这当中,“在里面”使用的最为频繁。
为什么要使用位置关系操作?有以下几个原因:
  • 准确定位页面对象。在挑战 D 中,我们提到了在一个 DOM 树中有可能存在与要查找的对象属性与 DOM 结构完全相同的对象。尤其对于“确定”或者“取消”按钮,这种情况很常见。这时,必须要通过限定父对象来缩小查找范围。一般来讲,只要限制到当前页面的边界元素能够阻止跨页面 DOM 节点查找就够了(因为,当前页面有哪些对象一目了然,但是其他页面的 DOM 节点是由运行时的操作控制的,无法预料)。
  • 封装 Dojo 小部件。这一点会在下面具体讲解。
  • 提供更丰富的查找方式,如根据“标签”查找 Dojo 小部件。通常,文本框的左侧会有一个文本,比如“名称:”。如果,该文本框没有任何其他合适的静态属性用来定位,就可以通过“在附近”查找的方法,先定位“名称:”所在的元素,再找到这个文本框。
  • 当 DOM 树结构未发生“功能性”变化时,避免自动化测试代码改动。所谓“功能性”变化是指页面上增加、替换或者移除了控件,比如按钮或者输入框等。当发生这些变化时,自动化测试代码不得不修改。但,如果发生的仅仅是 DOM 树结构上的变化,比如增加了不可见的 DIV 或者 SPAN 元素,只要位置关系操作使用得当,自动化测试代码可以做到不需要修改。
我们来看一个例子。图 2 左边是所测应用现在的状态:一个 Dojo 按钮小部件被一个 DIV 元素包围。在代码中,我们用按钮的文本“OK”并限制在图示的 DIV 中来定位它。之后,DOM 树结构发生了变化,变成了图 2 右边的样子,在原有的 DIV 元素和按钮之间增加了两层 DIV 元素。此时,代码不需要更改,因为这个“OK”按钮仍然在之前的 DIV 元素里。但是,如果用 XPath 定位元素,这种情况就很有可能要修改了。
图 2. 位置关系操作示例封装 Dojo 小部件在挑战 C 中,提到了 Dojo 小部件 DOM 结构的复杂性。最好的方式是封装 Dojo 小部件,将每个 Dojo 小部件作为一个整体操作。
Water Bear 使用的编程语言是 Java。它将页面中的 Dojo 小部件映射成一个 Java 类,以此封装所有该 Dojo 小部件的行为。由于 Sahi 支持“在里面”的位置关系操作,使得封装更加容易 – 只需要定位到 Dojo 小部件的最外层 HTMl 元素(一般是 DIV),其他的元素定位都限制在该元素之内。从而,即便页面上同时有两个同类型的 Dojo 小部件,也不会出现跨部件的错误操作。
图 3 展示了 Water Bear 中定义的与 Dojo 小部件对应的一些类。最上层父类 WebElement.java 代表一般的 HTML 元素,它封装了基本 HTML 元素的方法。DojoWidget.java 是所有 Dojo 小部件类的抽象。它定义了所有 Dojo 小部件类的通用方法,比如 getWidgetId()等。所有 Dojo 小部件类均继承自 DojoWidget.java 并定义自己的方法,比如 ComboBox.java 需要定义 selectByText 方法。
图 3. Water Bear 中与 Dojo 小部件对应的类那么,页面上 Dojo 小部件如何和这些类对应关联起来呢?Water Bear 中通过.wdef 文件把两者关联起来。
清单 2. .wdef 文件示例
1
2
3
4
5
6
org.waterbear.core.widgets.dijit.Textbox=div|textbox|labelnear|dijit_form_ValidationTextBox,\
evo_form_ObjectNameTextBox,dijit_form_NumberTextBox,dijit_form_TextBox,aspen_config_directory_DNTextBox
org.waterbear.core.widgets.dijit.Checkbox=div|checkbox|labelnear|dijit_form_CheckBox
org.waterbear.core.widgets.dijit.Select=table|table|labelnear|dijit_form_Select
org.waterbear.core.widgets.dijit.Button=span|span|labelinside|dijit_form_Button
org.waterbear.core.widgets.dijit.ComboBox=div|textbox|labelnear|dijit_form_ComboBox




清单 2 展示了.wdef 文件的部分内容。它是一纯文本文件,每一行定义了一组映射关系。等号左边是 Dojo 小部件映射的 Java 类名,等号右边是页面上 Dojo 小部件的属性描述。其中,起关键作用的是是最后一个属性,它是 widgetid 的前缀部分。一个 Dojo 小部件类可以关联到多种页面 Dojo 小部件,因为有些 Dojo 小部件虽然被扩展了,但是对 Web UI 自动化测试来说扩展的功能不会被涉及到,于是可以用同一个类表示。
返回列表