Tellurium 自动化测试框架介绍
简介
Tellurium 自动化测试框架 是由方剑在 2007 年 6 月创建的用于测试 Web 应用的框架,并在 2008 年 6 月移步到 Google Code 成为一个 开源项目 。它会定期发布版本,当前版本号是0.7.0。项目的核心已经历时两年,并繁衍出了多个子项目,包括:UDL、Core、Engine、Widget 扩展、Maven Archetype、Trump、Tellurium IDE、TelluriumWorks 以及参考项目。
这个框架是从 Selenium 框架 发展而来,但又具有不同的测试理念。大多数 Web 测试框架,比如 Selenium,主要致力于单独的 UI 元素。而 Tellurium 恰好相反,它把多个 UI 元素看作一个 Widget 整体,并将其称作 UI module。
拿 Google 搜索的 UI 做个例子,这个界面用 Tellurium 表示成如下这样:
ui.Container(uid: "GoogleSearchModule", clocator: [tag: "td"]){ InputBox(uid: "Input", clocator: [title: "Google Search"]) SubmitButton(uid: "Search", clocator: [name: "btnG", value: "Google Search"]) SubmitButton(uid: "ImFeelingLucky", clocator: [value: "I'm Feeling Lucky"]) }
正如你在例子中看到的,UI module 是嵌套的 UI 元素、tag 以及 attribute 的集合。Tellurium 在采用了 UI module 之后,更具表述性,对变化的响应也更加智能化。同时它也可以很容易地表示动态 Web 内容,并易于维护。
这个框架由以下组件组成:
- Trump ——一个 Firefox 插件,全称是 Tellurium UI Module Plugin,它可以在用户选择待测 Web 页面上的 UI 元素后,自动生成 UI module。
- Tellurium IDE _——_ 另外一个 Firefox 插件,可以记录用户操作,并生成 Tellurium 测试脚本,包括 UI module 的定义、用户的动作以及断言。测试脚本是用 Groovy 写成的。
- TelluriumWorks ——一个单独的 Java Swing 应用,用于编辑和运行 Tellurium 测试脚本。另外还在开发一个针对 IntelliJ IDEA 的 IDE 插件。
- JavaScript Widget Extensions ——针对流行 JavaScript 框架的扩展,比如 Dojo 和 jQuery UI。这样用户就可以在项目中引用发布的 Tellurium jar 文件,并在 UI module 定义中,把 UI widget 当作一个普通的 Tellurium 对象。
特性
主要特性包括:
- UI module 清楚地表示了待测的 UI。在 Tellurium 的测试代码中,并没有直接使用定位器(locator)。而是使用 uid 对象来引用 UI 元素,从而更具表现力。比如:
type "GoogleSearchModule.Input", "Tellurium test"
click "GoogleSearchModule.Search"
- 使用 UI 属性而不是固定的定位器来描述 UI。实际的定位器将会在运行时生成。如果属性改变了,新的运行时定位器也会由框架自动重新生成。Tellurium 从而可以按需自适应 UI 的变化。 Tellurium 0.7.0 中的 Santa 算法 通过一次定位整个的 UI module,从而进一步提高测试的智能性。此外还使用了 UI module 部分匹配机制,在一定程度上适应属性的变化。
- 采用了 Tellurium UI 模板 和 Tellurium UID 描述语言(UDL)来表示动态的 web 内容。
- 框架实行 UI module 和测试代码的分离,从而有利于重构。 比如,UI 和对应的测试方法定义在分离的 Groovy 类中。这样,测试代码就和 UI module 解耦了。
另外该框架还:
- 使用抽象的 UI 对象来封装 Web UI 元素
- 支持 Widget 以实现可重用性
- 为 UI 定义、动作和测试提供一门 DSL
- 支持组定位,从而一次定位一组 UI 组件
- 包括 CSS 选择器支持,以改善在 IE 中的测试速度
- 提供定位器缓存和命令集来提高测试速度
- 支持数据驱动测试
对比 Selenium 和 Tellurium
Selenium Web 测试框架是最流行的开源自动化 web 测试框架之一。它是一款独创性的框架,提供了很多独一无二的特性和优势,比如:基于浏览器的测试、Selenium Grid 以及使用 Selenium IDE 来“录制和回放”用户的动作。
然后,Selenium 有点问题。拿下面这段测试代码举个例子:
setUp("http://www.google.com/", "*chrome"); selenium.open("/"); selenium.type("q", "Selenium test"); selenium.click("//input[@value='Google Search' and @type='button']");
如果有人不是很熟悉 Google 的搜索页面,他能根据这段代码,说出页面的 UI 是什么样子的吗?定位器 q 在这里是什么意思呢?
万一因为 Web 的变化,XPath //input[@value=‘Google Search’ and @type=‘button’] 变成无效的了,怎么办?更有可能发生的是,这段代码需要逐行检查才能找出那几行需要更新的代码。
万一这段测试代码里面有几十上百个定位器怎么办?使用 Selenium IDE 生成测试代码,这可能在一开始比较容易,但归纳和重构起来就很困难了。
重构会是一个比从头生成新测试代码更乏味的过程。原因在于硬编码的定位器和使用的测试代码耦合太紧密了。因为测试代码没有结构化,维护代码就变得异常困难。
作为一个低层次 Web 测试驱动框架,Selenium 是一个很好的框架。然而,它需要投入更多的努力才能创建出智能的测试代码。
Tellurium 就是为解决 Selenium 中的大多数问题而诞生的。
Tellurium 同时被设计用来解决 Selenium 的其他弱点。比如,IE 性能一直是 Selenium 突出的问题。Tellurium 的解决方案是,使用 CSS 选择器来作为缺省的定位器。定位器由 UI module 自动生成,并改善了测试速度。
另外,在采用了 Tellurium UI module 缓存以及基于新的 Tellurium 引擎的命令集之后,测试速度得到进一步的提升。Tellurium 还支持对 Ajax 应用的测试:Tellurium 的 List 和 Table UI 对象被用来在运行时表示动态 Web 内容。而 option 对象则被用来在运行时表示同一 Web 元素的两个不同 UI。
与 Selenium 一样,Tellurium 可以用来测试任何基于 HTML DOM 结构的 Web 应用。
测试方法
Tellurium 采用一种新的方式,通过 UI module 的概念来进行自动化测试。使用对象封装 Web UI 的元素,因此不再需要手动生成和重构 UI 的定位器。UI module 是个简单的复合 UI 对象,由嵌套的基本 UI 对象组成。
这个框架可以在两种模式下运行。第一种模式是作为 Selenium 框架的 wrapper 来工作。也就是说,Tellurium core 基于 UI module 中的 UI 对象属性,生成运行时定位器。生成的运行时定位器然后通过 Tellurium 扩展传递给 Selenium core 来调用。
Tellurium 还在开发它自己的驱动引擎,即 Tellurium Engine,以更好更有效地支持 UI module。
- 首先,Tellurium Core 把 UI module 转换成 JSON 的表示形式。
- 然后在使用 UI module 时,JSON 表示的数据被第一次传递给 Tellurium Engine。
- 接着 Tellurium Engine 使用 Santa 算法,定位整个 UI module,并将其存在缓存中。
- 在接下来的调用中,会直接使用缓存的 UI module,而不需要重新定位了。
- 此外,Tellurium Core 把多条命令合并成一条批处理命令,叫做宏命令,然后在一次调用中把这条批处理发送给 Tellurium Engine。这样可以减少请求 / 响应带来的延迟。
下面这个例子,使用了该项目网站上的问题搜索 UI,来表述框架背后的思想。
我们从为问题搜索的 UI 定义 UI module 开始吧:
ui.Form(uid: "issueSearch", clocator: [action: "list", method: "GET"]) { Selector(uid: "issueType", clocator: [name: "can", id: "can", direct: "true"]) TextBox(uid: "searchLabel", clocator: [tag: "span", text: "for"]) InputBox(uid: "searchBox", clocator: [type: "text", name: "q", id: "q"]) SubmitButton(uid: "searchButton", clocator: [value: "Search", direct: "true"]) }
然后使用下面这个测试方法:
public void searchIssue(String type, String issue){ select "issueSearch.issueType", type keyType "issueSearch.searchBox", issue click "issueSearch.searchButton" waitForPageToLoad 30000 }
如果有一天,你需要把 Selector 修改成输入框,那我们只需要更新对应的 UI module:
ui.Form(uid: "issueSearch", clocator: [action: "list", method: "GET"]) { InputBox(uid: "issueType", clocator: [name: "can", direct: "true"]) TextBox(uid: "searchLabel", clocator: [tag: "span", text: "for"]) InputBox(uid: "searchBox", clocator: [type: "text", name: "q", id: "q"]) SubmitButton(uid: "searchButton", clocator: [value: "Search", direct: "true"]) }
然后修改命令:
select "issueSearch.issueType", type
为:
type "issueSearch.issueType", type
其余则保持不变。
如果有动态的 Web 内容,比如 Google Books 的网站,它包含了一个图书分类的列表,每个分类中包含一个图书列表。针对这样 UI 的 UI module 会出奇的简单:
ui.Container(uid: "GoogleBooksList", clocator: [tag: "table", id: "hp_table"]) { List(uid: "subcategory", clocator: [tag: "td", class: "sidebar"], separator: "div") { Container(uid: "{all}") { TextBox(uid: "title", clocator: [tag: "div", class: "sub_cat_title"]) List(uid: "links", separator: "p") { UrlLink(uid: "{all}", clocator: [:]) } } }}
Tellurium UID 描述语言 为定义动态 Web 内容提供了更多的灵活性。我们来看个复杂点的例子。
ui.StandardTable(uid: "GT", clocator: [id: "xyz"], ht: "tbody"){ TextBox(uid: "{header: first} as One", clocator: [tag: "th", text: "one"], self: true) TextBox(uid: "{header: 2} as Two", clocator: [tag: "th", text: "two"], self: true) TextBox(uid: "{header: last} as Three", clocator: [tag: "th", text: "three"], self: true) TextBox(uid: "{row: 1, column -> One} as A", clocator: [tag: "div", class: "abc"]) Container(uid: "{row: 1, column -> Two} as B"){ InputBox(uid: "Input", clocator: [tag: "input", class: "123"]) Container(uid: "Some", clocator: [tag: "div", class: "someclass"]){ Span(uid: "Span", clocator: [tag: "span", class: "x"]) UrlLink(uid: "Link", clocator: [:]) } } TextBox(uid: "{row: 1, column -> Three} as Hello", clocator: [tag: "td"], self: true) }
在这个例子中,我们是使用元数据“first”、数字和“last”来指定 header 的位置。元数据“{row: 1, column -> One} as A”意味着我们例子中的 UI 元素——一个 TextBox,处于第一行,并和 header“One”处在同一列。测试代码很干净,比如:
getText "GT.A" keyType "GT.B.Input", input click "GT.B.Some.Link" waitForPageToLoad 30000
未来计划
Tellurium 是一个年轻而且创新的项目,它具有许多来自开发团队和用户社区的新颖思想。Tellurium 希望在以下领域继续发展:
- Tellurium 0.7.0 已经实现了一个新的使用 jQuery 的测试驱动引擎。这个引擎的主要特性包括:UI module 组定位、UI module 缓存、命令集处理、用 jQuery 重新实现的 Selenium API 以及新的 Tellurium API。Tellurium 会继续开发这个新引擎直至完备。
- Tellurium IDE module 插件 0.8.0 RC1 刚刚发布,它包含了很多新的特性。录制和生成测试脚本的 Tellurium IDE 的 RC 版本也已发布。它们是 Tellurium 成功的关键,因此会得到持续的改进。除了 Trump 和 Tellurium IDE,Tellurium 还在计划改善 TelluriumWorks,让它可以编辑、完成语法检查,并运行 Tellurium DSL 测试脚本。
- Tellurium 作为云测试工具是另外一个非常重要的发展方向。项目团队正在计划重新考虑整个架构,使其可以更直接地并行执行测试。通过 P2P 技术,只需最少的管理,就让测试服务器在云的环境中具备自组织和自协调的能力,这是件极具挑战性的工作。
Tellurium 框架还希望发展的其他领域包括:
- 创建可重用的 Dojo、ExtJS 和 jQuery UI Tellurium widget。这样可以让其他人只需要在自己的项目中包含对应的 jar 文件,就可以重用这些 widget。
- 支持行为驱动测试。
- Web 安全测试
- 支持其他的语言,比如 Ruby
关于作者
方剑毕业于乔治亚理工学院,电子和计算机工程专业博士学位。他的工作是某 IT 公司的高级软件工程师,致力于设计和实现企业级应用软件。他是 Tellurium 自动化测试框架项目的创建者。
查看英文原文: Introducing the Tellurium Automated Testing Framework
感谢 张龙 对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组 中与我们的编辑和其他读者朋友交流。
更多内容推荐
-
Google 发布新一代 Web UI 库 Polymer
在今年的Google I/O大会上,Google发布了Polymer,它是一个使用Web组件构建Web应用的类库,同时也使用了为Web构建可重用组件的新的HTML 5标准。Polymer为大部分Web组件技术提供了polyfills功能,它能让开发者在所有的浏览器支持新特性前创建自己的可重用组件。
语言 & 开发 -
视觉感知测试
对于界面布局,传统的测试都是由人工对比设计图和产品界面。当界面有修改之后,再由人通过肉眼去检查修改(包括正确的和错误的修改),这样即费时而且测试结果又不稳定,因为人是有情绪的。但是我们认为如果一个界面通过第一次的人工验证并发布之后,它就是一个正确的标准界面,并且是包含了人工测试价值的资产。当下一次测试的时候,这部分价值就应该被保留并重用起来,用于减少新的一次测试的时间,从而实现界面的快速回归测试。为了解决上面提到的各种问题,视觉感知测试孕育而生。它使用传统的对图片进行二进制比较的办法,结合敏捷迭代开发的理念,产生的一种针对界面布局的自动化测试方法。
-
加餐 01|留言区心愿单:真·子组件以及 jsx-runtime
在本专栏选用的React 18.2.0版本和与它配套的CRA中,新JSX运行时也是被默认启用的。
2022-09-20
-
01|认识 React:如何创建你的第一个 React 应用?
通过一个实战项目,创建你的第一个React应用。
2021-05-24
-
基于 Selenium 和 Python 的 web 自动化框架
本文使用Python结合Selenium WebDriver库进行自动化测试框架的搭建。
-
行为驱动开发在携程机票前端研发流程中的实践
本文转载自公众号携程技术(ID:ctriptech)。
文化 & 方法 -
22|质量保证(上):每次上线都出 Bug?你需要 E2E 测试
接下来两节课,我们将进入大中型React项目最重要的实践之一:自动化测试的学习。
2022-10-20
-
Dojo:不容忽视的 RIA 框架
现在的前端开发有太多可选框架,不乏JQuery这样炙手可热的产品。但我相信,如果要为你的项目做一个技术决策,选择合适的框架,仍然不是一件容易的事情。Dojo是这个领域的先行者,但其强大的特性却一直被忽视。专栏开篇就会系统介绍Dojo的性能、控件、单元测试等重要特性,让你通过一个综合了解,为高效的RIA开发多一个重量级的选择。
-
程序员练级攻略:UI/UX 设计
我并不认为UI/UX设计这些内容只是设计师要学习的,如果你要成为一个前端程序员,那么学习这些设计上的东西可以让你有更好的成长空间。
2018-08-07
-
Flutter UI 自动化测试技术方案选型与探索
Flutter页面无法直接使用Native测试工具定位元素,给自动化测试带来很多不便。
-
Telerik 宣布 Coded UI 测试支持 WPF
Telerik RadControls for WPF Q3 2012控件库支持级别1的Coded UI 测试,允许开发者测试用户界面。
语言 & 开发 -
Dojo 1.4 发布:性能改进、稳定性提升
近日Dojo团队发布了Dojo 1.4,该版本的性能和稳定性都得到了极大的提升,同时增加了大量的新特性。
-
开源自动测试框架 Tellurium
Tellurium是一款针对web应用、基于UI模块的并配有一套领域特定语言来进行web测试的自动测试框架。最近Tellurium发布了0.6.0版本,InfoQ中文站就此采访了Tellurium的创始人方剑先生。
-
WebTest 比拼 Selenium:模拟和真实浏览器上的测试
在选择功能性测试工具的时候,是选择那些驱动真正的Web浏览器的(如Selenium)呢?还是那些模拟浏览器行为的(Canoo WebTest)呢?Marc Guillemot将这两种工具进行了对比,根据他的观点,WebTest以13:5的比分获胜。
评论