目录
图 3. Water Bear 中与 Dojo 小部件对应的类
前言:
Dojo是一个流行的JavaScript框架,用于构建富客户端Web应用程序。在开发和维护Dojo应用时,UI自动化测试是至关重要的。它可以帮助测试人员验证应用的功能和用户界面,并确保其在不同浏览器和设备上的一致性。
虽然本文探讨的主题是 Dojo 应用的 UI 自动化测试,但不少内容也适合其他的 Web 2.0 应用。希望读者朋友或多或少都能从中获益。
Dojo 是什么?
Dojo 是一个 JavaScript 实现的开源 DHTML 工具包。它是在几个项目捐助基础上建立起来的(nWidgets,f(m),Burstlib) 。 Dojo 的最初目标是解决开发 DHTML 应用程序遇到的一些长期存在的历史问题,现在,Dojo 已经成为了开发 RIA 应用程序的利器:
- Dojo 让您更容易地为 Web 页面添加动态能力,您也可以在其它支持 JavaScript 的环境中使用 Dojo ;
- 利用 Dojo 提供的组件,您可以提升 Web 应用程序的可用性和交互能力;
- Dojo 很大程度上屏蔽了浏览器之间的差异性,因此,您可以不用担心 Web 页面是否在某些浏览器中可用;
- 通过 Dojo 提供的工具,您还可以为代码编写命令行式的单元测试代码。
Dojo 的打包工具可以帮助您优化 JavaScript 代码,并且只生成部署应用程序所需的最小 Dojo 包集合。
Dojo 应用 UI 自动化测试面临的挑战
Dojo 应用 UI 自动化测试面临的挑战可以归为两类:开发阶段的挑战和维护阶段的挑战。
开发阶段的挑战:
- 异步请求的处理
- 元素定位
- Dojo 复杂性
- 产品复杂性
维护阶段的挑战:
- 频繁的 UI 更改
- Dojo 升级
下面,我们具体讲解每一种挑战。为了后文讲解设计原则时能方便的对应到这些挑战,我们用英文字母标记每个挑战。
A. 异步请求的处理
在传统的 Web 应用中,用户每点击页面上的超链,浏览器就会向服务器发出一个请求,等待服务器做出响应,然后返回一个完整新网页,但在大多数情况下用户不得不忍受页面闪烁和长时间的等待。为了解决传统的 Web 应用中出现的问题,出现了 Ajax。通过使用 Ajax 页面和应用向服务器请求它们真正需要的东西,也就是页面中需要修改的部分,服务器就提供哪部分,这使得通信量更少,更新更少,用户等待页面刷新更短,用户更加满意。
但是,Ajax 的到来对 Web UI 自动化测试却未必是好消息。Web UI 自动化测试框架的执行方式类似于一个“队列”:用户定义了一系列的页面操作和验证,之后 Web UI 自动测试框架把它们按顺序一一执行。在传统 Web 应用中,由于每次向服务器端发起请求都会导致页面跳转,Web UI 自动化测试框架能很容易地判断出合适该执行下一个动作。 但是,Ajax 的行为是异步的,也就是说,用户的操作跟服务器端的处理现可以是并行的,不存在严格的顺序。起初,这给 Web UI 自动化测试框架的开发者带来了困扰,而且很长一段时间里这个问题都没有被很好的解决。
起初,Web UI 自动化测试开发人员主要有两种解决方案:硬编码等待时间和基于条件的等待。
硬编码等待时间: 这种方式是指在代码中指定一个静态等待时间,比如指定等待 30 秒后执行下一个操作。通常,这种数值的设置来源于经验。可以想象,如果这个等待时间比实际等待时间小,自动化脚本执行就会失败。而且,不幸的是,这样情况的确经常发生。随着测试环境的变化,实际需要的等待时间事实上是一个变量。以下几个因素都有可能导致它发生变化:
- 测试服务器在远程还是本地:毫无以为,由于网络的影响,服务器如果在远程,等待时间就会增加。
- 使用的浏览器: 浏览器 JavaScript 引擎的执行速度对等待时间也有影响。根据经验, Firefox 和 Chrome 都比 IE 要快。因此,如果用的是 IE,等待时间也会增加。
- 测试运行时的网络环境:如果测试时的网速较慢,等待时间会增加。
- 测试服务器的负载:测试服务器可能是独占也可能是共享的。如果自动化测试执行时的服务器负载较大,也会导致等待时间增加。
对于上述硬编码等待时间的问题,Web UI 自动化测试开发人员一般有如下对策。
- 尽量将等待时间设置的大一些。这样做存在一些问题。一来未必能保证在任何情况下该值都足够大;二来它意味着无论服务器在本地还是远程浏览器是快是慢,执行时间都一样,这对于服务器在本地以及浏览器比较快的测试环境是很大的时间成本浪费。
- 设置放大因子。这种方法是在编码的时候给等待时间乘上一个因子。这个因子或者是硬编码的,比如定义在一个参数文件中。当测试环境比较好的时候,设置小一点;测试环境比较差的时候,设置大一点。 高级一些的,可以动态地设置这个因子。比如,可以把某一个操作的执行时间作为计算该因子数值的参照。这个方法使情况得到了部分改善,但是仍然不能保持其执行的稳定性。
基于条件的等待: 由于硬编码等待时间方式的不稳定性,Web UI 自动化测试框架开始支持“基于条件的等待”。这种方式是采用“轮询”的机制判断是否可以开始执行一个操作。假设,当前要执行的操作是一个按钮点击动作。这个按钮默认是被禁用的,当页面从服务器端加载了数据之后这个按钮才被启用。因此,如果要保证这个操作成功,就需要“轮询”这个按钮的状态 – 直到发现它被启用了,才执行点击操作。 如果由于存在 bug 按钮一直不启用怎么办?所以,基于条件的等待的方法需要设置“超时时间”。如果超过这个时间按钮还没有启用,就认为这个测试用例失败了。所以,大家发现了,这个超时时间的设置其实还是个“硬编码等待时间”,所以某种程度上,这种方式仍存在硬编码等待时间方式的弊端。这种方式的另外一弊端是它带来了额外的编码成本,并且自动化测试代码中可能充斥了许多条件判断代码,而它们本身不完成我们的“业务”目标,仅是辅助代码。
B. 元素定位
一般的 Web UI 自动化测试编码无非包含这样几个步骤:定位及获取元素,执行操作以及验证结果。而且,通常 Web UI 自动化测试开发人员在元素定位和获取这个步骤上花费相当多的时间。大多数 Web UI 自动化测试开发人员希望所需获得的元素能有一个静态 id 属性。根据规范,id 属性的值在 DOM 树中必须是唯一的,因此通过 id 属性就可以很简单并且准确地定位元素。但是,这样的需求常常不是产品的需求,而只是为了满足 Web UI 自动化测试代码开发的简便。所以,对于产品开发人员来说,给每个需要在 Web UI 自动化测试中使用到的元素增加静态 id 属性不是高优先级的工作。而且,从技术角度上讲,有些 Dojo 应用中的元素也无法设置静态 id 属性。
对于 Dojo 应用,情况又复杂了一些。图 1 展示的是一个 Dojo 按钮小部件在 Firebug 中呈现的 DOM 结构。最外层的 SPAN 元素上有一个 widgetid 属性,内部的 SPAN 元素上定义了 id 属性,共同点是它们都是由一个前缀和一个动态的数字构成的。这个数字是