基于 SWTBot 进行 Eclipse GUI 自动化测试

背景简介

在软件开发领域,持续集成和部署对于软件测试自动化提出了越来越高的要求,基于 Eclipse 应用在这一需求中仍然占据重要的组成部分。目前主流的测试自动化工具主要以录制回放的功能为主,辅助以脚本的方式实现。然而,基于此的测试方法往往具有测试用例维护复杂,测试过程容易失败的问题,这直接影响了测试效率。
SWTBot 作为 Eclipse 官网推荐的自动化测试工具,提供了专业的类库以及扩展点,在 Eclipse 应用的自动化测试中具有先天的优势。

SWTBot 是基于 Eclipse SWT 的开源的 UI 和功能测试工具,具备简单易用的 API 支持,对于基于 Eclipse 富客户端 (Rich Client Platform) 搭建的应用具有天然的兼容性,使之能够帮助用户快速有效地构建特定应用的自动化测试框架。

目前,大部分 Eclipse 自动化测试工具主要采用录制-回放的工作模式创建测试用例,同时通过脚本来维护业务逻辑,往往一个测试要涉及到多个脚本的维护,这大大提高了对于测试人员的要求,而录制-回放的方式也由于其机制的不稳定性,往往使得测试无法在特定的时间内得到准确的结果。

SWTBot 自创建至今,已在 Eclipse 社区得到极大地改进和推广,使之日趋稳定和成熟。本文提出一种基于 XML 描述测试用例、同时支持用户 UI 操作语言的测试框架,意在能够:

  1. 降低对开发人员的技术要求,使之专注于操作流程和业务逻辑
  2. 提供可扩展的测试用例描述格式,提供测试用例的复用能力
  3. 建立 Eclipse UI 操作的基本术语,提高框架的扩展能力
  4. 自动化输出测试结果,提高测试人员的生产力

体系结构

本文基于 SWTBot 的开源框架,扩展其对于 Eclipse 基本控件的支持、封装和实现操作元语言,改进其效率,实现了一种在较低维护成本下便能够适应新场景的自动化测试框架。同时,本文中提出,所用测试用例基于 XML 进行描述,提供统一的测试描述语言及解析方式。

该自动化测试框架(以下简称“该框架”)的体系结构如下图所示:

图 1. 基于 SWTBot 的 Eclipse UI 自动化测试框架体系结构

基于 SWTBot 进行 Eclipse GUI 自动化测试

作为该框架的唯一输入,我们采用 XML 作为统一描述测试用例的语言。在下文中,将介绍我们从特定应用中抽象并定义的 XML 元语言及操作,一个复杂的测试步骤将由若干元语言及操作构成,测试步骤的集合构成测试用例 (Test Case),测试用例的集合构成测试集 (Test Suit)。

该框架最底层包含了 SWTBot 类库,在该类库中,实现了对于 Eclipse 基本控件的识别与检索方式。从下而上,在该框架的倒数第三层中,我们在 SWTBot 基础类库的基础上,扩展实现了针对特定控件的支持,譬如分页组合的控件,从而确保在测试执行中,可以方便找到特定应用中的特定控件。这样做的好处便在于,不同产品可以复用已实现的控件,同时扩展所需要的控件。同时,为提高控件检索的效率,以及支持测试逻辑的实现,我们实现了 Utilities 工具集,用来维护测试用例中的标准输入输出,以及生成测试结果的源数据,并且加快执行效率。

在该框架的最顶层,是对标准输入 XML 格式的测试用例的支持。通过属性文件的定义,该框架能够快速解析在特定目录下所有测试集,并建立先后执行的顺序,依次执行,同时记录每个测试步骤的执行状态,并且根据属性文件中的定义,判断遇到错误是退出或是继续执行。

 

测试用例

基于 XML 的测试用例描述

现在,我们站在一个测试人员的角度来演示一下,利用这个扩展的 SWTBot 测试框架,测试人员的工作将变得多么的简单。而且,通过使用 XML 作为测试用例的描述工具,更加方便了测试人员撰写测试用例的过程,大大降低了对测试人员编码能力的要求,使测试人员能够专注在撰写 XML 测试用例这一件唯一的事情上。

创建测试工程

第一步,测试人员需要创建一个空的工程。比如,这里测试人员创建了一个名为“com.ibm.team.enterprise.swtbot.sample”的测试工程。紧接着,测试人员又创建一个文件夹 sampleTestsuit 来放置测试描述文件。这个文件夹下包含了一个 Properties 文件夹,用来存放属性文件。然后,测试人员可以根据需要添加若干个测试用例 (Test Case),这里我们添加了 2 个测试用例:SampleTestCase1.xml 和 SampleTestCase2.xml。这样,测试工程就创建好了,它的结构如图所示:

图 2:基于 XML 描述的测试工程结构图

基于 SWTBot 进行 Eclipse GUI 自动化测试

接下来,测试人员所有的工作就是专注在写 XML 测试用例上。并且,通过 Eclipse 自带的 XML 编辑器,测试人员甚至都不需要关心 XML 的语法,只需要在模板里面一步一步添加 Command 并提供相应的值即可。

图 3:用 XML 文件来描述 GUI 测试用例

基于 SWTBot 进行 Eclipse GUI 自动化测试

举一个例子,假设测试人员希望在 FirstTestStep 的最后一个 Command 之后再添加一个点击按钮的动作。那么他只需要右击选择”Add After”,选择 Command 选项。然后用同样的方法给这个 Command 命令添加属性,这真的非常简单,大大方便了测试人员的工作。

Properties 配置文件

在一个测试工程里,Properties 配置文件定义了一系列的键/值对。Propertires 文件的作用有两个。第一个作用是定义变量,以便可以在 XML 测试用例中引用它们。引用变量的方法也很简单,通过${变量名} 的格式来引用即可。比如上面的例子中${BUTTON_SUMMIT} 就引用了 sampleTestSuite.properties 文件中定义的变量 BUTTON_SUMMIT,这对于提高 XML 测试用例的移植性和扩展性都很有帮助。Properties 配置文件的第二个作用是外部化,UI 上的所有 Widget 文本都被赋予一对唯一的键/值,这样在 UI 全球化过程中,不同的 Widget 文本根据不同的语言环境设置不同的值,这时候,Properties 文件中定义的这些外部化变量就显得尤为重要。

图 4: 测试工程的 Properties 属性文件

基于 SWTBot 进行 Eclipse GUI 自动化测试

 

框架实现

SWTBot 作为 Eclipse 官方推荐的 UI 自动化测试工具,它本身是基于 Hamcrest 和 JUnit 来执行用 Java 语言写成的测试用例 (TestCase) 和测试集 (TestSuit)。但是这样就要求测试人员必须要精通 Java 语言并且能够熟练掌握 JUnit。由于我们改变了 SWTBot 的执行目标文件并使之成为我们自定义的 XML 形式的测试用例文件,实现了一个基于 XML 语言的 Eclipse UI 自动化测试框架。这样,测试人员从此可以摆脱繁重的代码工作,把工作重心放到实际测试对象的业务逻辑上。利用 SWTBot 最核心的测试 UI 的执行部件,加上对其核心部件 Finder、Matcher、Widget、Condition 以及 Assert 等的扩展和丰富,构成了该框架实现的主要内容。

原生 SWTBot 的执行原理

在详细介绍该框架如何实现之前,首先大家需要对 Eclipse 自身的架构有一个深入的认识,什么是插件 (Plug-in),什么是扩展点 (Extension Points),什么是扩展 (Extensions),什么是依赖 (Dependencies),什么是 OSGI(开放服务网关协议) 等等。然后需要了解 Eclipse 富客户端 (RCP) 的主要组成部分工作平台 (Workbench),视图 (View),编辑器 (Editor) 和透视图 (Perspective) 的基本原理和基本操作。这些基础知识请到参考资料中自行学习,这里就不再累述。 接下来我们来了解一下 SWTBot 的基本执行原理和执行顺序。我们使用 SWTBot 就是要模拟用户对于 Eclipse RCP 应用的各个部件的操作并且加入验证点来检验操作执行的结果。 SWTBot 本身是 Eclipse 的一个应用程序 (Application),只是实现了 Eclipse 本身的一个测试接口 ITestHarness。当被测试的应用程序启动以后,Eclipse 就会启动 SWTBot 这个应用程序,来加载通过命令行定制的 JUnit 的测试用例和测试集,接着通过 SWTBot 的 SWTWorkbenchBot 工厂类在被测试程序里面去寻找工作平台,以及在工作平台上捡索被测试的部件来初始化对应的 SWTBot 部件实例,通过对这个 SWTBot 的部件实例进行相应的操作,最后将操作的执行结果返回给 SWTBot 进行验证。乍一看,整个执行过程比较简单,似乎使用起来也是水到渠成。但是调用哪一个 SWTBotFactory 工厂类提供的静态方法获得相应的被测试控件对应的 SWTBot 对象,以及对对象进行操作都需要深入了解富客户端程序的基本构成和操作本质。我们的框架简化了对于控件的检索和操作,只需要按照我们定义的 XML 元数据的规范指定简单的 XML 元素和设置相应的属性值,就可以方便地查找元素、操作元素和设定测试的验证点。

基于 SWTBot 基本控件的扩展

我们的框架首先在 SWTBot 的 Finder 组件中加入了对于多层编辑器 (MultipleEditor) 和编辑器里面的每个章节(Section)的支持。这样用户可以方便地有针对性的对这种复杂的编辑器和章节进行对应的测试操作,而不用像 SWTBot 原来那样在笼统的一种基本的编辑器里面操作。然后,在 SWTBot 的 Widget 组件中,新加入了对组合部件 (Composite)、滚动表单 (ScrolledForm) 和表单页面 (FormPage) 等部件的支持。最后,特别在 SWTBot 的 Matcher 组件里增加根据不同条件寻找部件的方法和丰富了多级右键菜单的操作方式,进一步扩展了原来 SWTBot 不能很好支持的领域,大大增强了 SWTBot 在 Eclipse RCP 自动化测试上的测试能力。

图 5:对 SWTBot 的 Matcher 组件的扩展

基于 SWTBot 进行 Eclipse GUI 自动化测试

图 6:对 SWTBot 的 Widgets 组件的扩展

基于 SWTBot 进行 Eclipse GUI 自动化测试

提高控件检索效率的方法

对于 SWTBot 检索控件的原理,如果大家详细的研读过它的源码,应该非常清楚。SWTBot 对于每一个 SWT 的控件都有一个对应的 Bot 对象来封装对于这个控件的操作和获得控件的属性及状态。同时 SWTBot 有一个 SWTWorkbenchBot 类,它是 SWTBot 里面几乎所有 Bot 对象的工厂类,是寻找这些 Bot 对象的基本入口。这个工厂类一般都是直接被创建出来,默认检索控件的路径就是从 Eclipse RCP 的总工作平台 (Workbench) 开始,然后从这个工作平台的所有视图、菜单、右键菜单、工具栏、状态栏和编辑器等地方去寻找需要测试和操作的控件对象,进而创建出 Bot 对象。这种控件检索方式下,执行效率肯定很低。我们的自动化框架优化了这种笼统的检索控件的方法,增加一个叫做操作区域 (Operation Area) 的对象,能够精确的将检索开始的地方定位到相应控件被包含的视图或者编辑器,缩小检索的范围,增加检索的准确性,提高了 SWTBot 的运行效率。

清单 1:获得操作区域的核心代码
 OAType oaType = oa.getType();
String id = ModelUtil.getLastOutputValue(oa.getID(), lastStepOutput);
String title = ModelUtil.getLastOutputValue(oa.getText(),
lastStepOutput);
SWTBotWorkbenchPart<? extends IWorkbenchPartReference> oaPart = null;
if (OAType.VIEW == oaType) {
oaPart = bot.showView(id, title);
} else if (OAType.EDITOR == oaType || OAType.TEXTEDITOR == oaType) {
if (null != id && id.length() > 0) {
oaPart = bot.editorById(id);
}
if (null == oaPart && null != title) {
oaPart = bot.editorByTitle(title);
}
if (OAType.TEXTEDITOR == oaType && null != oaPart
&& oaPart instanceof SWTBotEditor) {
oaPart = ((SWTBotEditor) oaPart).toTextEditor();
}
} else if (OAType.EEMULTOPLE_EDITOR == oaType) {
if (null != id && id.length() > 0) {
oaPart = bot.multipageEEEditorById(id);
}
if (null == oaPart && null != title) {
oaPart = bot.multipageEEEditorByTitle(title);
}
if (null == oaPart && null == title && null == id) {
oaPart = bot.getActiveEditor();
}
} else if (OAType.PERSPECTIVE == oaType) {
SWTBotPerspective perspective = null;
if (null != id && id.length() > 0) {
perspective = bot.perspectiveById(id);
}
if (null == oaPart && null != title) {
perspective = bot.perspectiveByLabel(title);
}
if (null != perspective && !perspective.isActive()) {
perspective.activate();
EESWTBotAssert.assertPerspectiveActivate(perspective);
if (null != title && title.length() > 0) {
Assert.assertEquals(
"The founded operation area is not exepcted.",
title, perspective.getLabel());
}
}
}

结束语

对于做过自动化测试的人员,相信大家都有体会,跟 Web 测试等其它领域比起来,本地 GUI 的自动化测试一直是比较难的部分,一直以来就没有一种既稳定高效又轻量级的 GUI 测试工具出现。另一方面,相比年轻的 Web 领域,本地 GUI 一直还是占据着软件开发市场很大的一部分,尤其是 Eclipse 等富客户端一直是企业软件从业人员开发的必备利器。所以,开发本地 GUI 的自动化测试工具,对于人力成本和时间的节省也是巨大的。

SWTBot 是开源的基于 Eclipse SWT 的 UI 和功能测试工具,通过这篇文章,相信大家对于我们这个基于 SWTBot 的 GUI 自动化测试框架有了一定的了解。由于只需要专注在写 XML 测试用例这一件事情上,对于广大的测试人员开发出高质量可重用的测试用例是有很大帮助的。本系列的第一篇文章暂告一段落,后续文章将更详细地介绍基于 SWTBot 扩展的 GUI 自动化的流程细节和场景,敬请期待。

参考资料

学习

上一篇:Linux CPU占用率监控工具小结


下一篇:洛谷—— P1092 虫食算