摘要
桌面应用程序与浏览器端的自动化测试都已经历了十年的发展,无论是从工具上还是项目管理方法论上都已经趋于成熟。而移动设备端应用程序的自动化测试近两年才刚起步,似乎一切尚处于探讨与研究阶段。但我们似乎已经看到其爆炸性的需求增长势头。可以从这两方面着眼分析:其一,移动应用从数量上和逻辑复杂程度上的增长,以及产品发布周期的紧缩,使得快速回归测试迫在眉睫;其二,安卓系统的开放性造成硬件厂商百家争鸣的局面,设备款式之多,迫使移动应用的兼容性测试提上日程。纵观当前智能手机两大主流阵营iPhone与Android,似乎安卓应用开发商与设备制造商更能体会兼容性测试的切肤之痛。鉴于此,并结合传统桌面系统上的自动化测试经验,我们在此探讨基于Android平台应用程序的关键字驱动自动化测试的可能性,并摸索一条适合在移动应用开发过程日新月异的现实情况中切实有效的实现和实施自动化测试的路子。

理论基础

在传统的桌面应用软件与浏览器端应用的自动化测试领域,已经有相当成熟的工具可供用户选择,例如商业工具HP QTP, IBM Robot/RFT, Borland SilkTest等;开源工具如Selenium, Watir等。剖析这些工具,它们似乎都有着相同的功能结构:

Ø 对被测应用界面对象/界面元素的捕获与识别,并对其进行管理与操作;
Ø 对于测试脚本的编辑功能与语法解析功能;
Ø 对于测试数据的组织与管理;
Ø 对于脚本执行结果的分析与输出;

如果细说,还可以牵扯到如脚本录制功能,插件管理功能,与测试管理工具、缺陷跟踪工具的整合等内容,涵盖面相当广泛。但所有这些都是为了一个目的:模拟测试人员行为,达到功能性回归测试的目的。本文尝试从以下关键的几点来分析自动化测试工具的核心构成部分。

1. 关键字驱动

关键字测试的主要思路是以面向对象的方式来管理被测应用的对象、对象的相关操作、测试数据以及这些测试数据之间的组合关系。关键字驱动是自动化测试中行之有效的方式,它可以帮助测试工程师更方便的维护测试脚本、构建复杂的业务逻辑测试用例、并节省手工测试的执行时间(尤其是在回归测试阶段)。关键字驱动主要由以下三种元素构成:

1.被测对象,即被测应用界面上的元素;
2.针对这些对象的操作,如点击(按钮)、填充(文字)、选择(单选框/多选框);
3.以及基于这些操作的数值;

上述三种元素可以描述为以下表格:

对象操作数值
文本框输入文本值
按钮点击无
选择框选择选项值
或者以面向对象的文法表述为:
对象.操作(值)
该语句是关键字驱动脚本的构成基础。

2. 对象库

对象库是用于储存被测应用程序界面对象(界面元素)的地方。它是关键字驱动测试工具的关键点。有了它,用户可以更容易的维护被测对象、更快速的构建测试脚本。它是如何做到这些的呢?让我们看看下面的结构:

如果对象都保存在对象库,它们可以被集中管理。与此同时,测试脚本(一个或多个)可以根据自身也许需求随意调用这些对象来使用。这使得多位测试工程师协同开发测试脚本成为可能。

对象库也可以分为两层,一层面向用户视角,另一层面向程序视角。这两层之间的对象是一一对应关系。这样做有助于测试脚本(测试用例)独立于被测应用程序。例如,应用程序的界面对象Obj 1改变了,但所有引用了该对象的测试脚本无需改动,因为它们是引用的对象Obj A,而非直接引用Obj 1。

3. 测试数据组织结构

当我们提到测试用例的时候,通常指的是一系列操作步骤以及针对这些步骤所用到的测试数据。在之前的章节中,我们已经探讨了基于被测对象的操作步骤,现在我们来谈谈测试数据相关的内容。
测试数据,通常可以理解为填入被测表单各个字段中的数值。这些数值需要被很好的组织和保存,以防止数据冗余。可问题是,如何有效的组织和存放这些数据?
在前面关于对象库的文章中,我们可以看到,其实测试数据也可以像对象那样被保存于数据库。可以存于数据库的表中,也可以存在表格文件,如Excel或.csv文件。这些表中的字段(表结构)需要跟被测表单中的字段一一对应。

在每次测试迭代中,测试用例从数据表中挑选其中一条数据用以执行,所以,表格中的数据需要设计为可重复利用的。当然,期望结果也可以存放于表格中,例如,这次操作的期望结果或返回值。
至此,我们已经讨论了关键字驱动的测试脚本、对象库和测试数据的组织。这几样应该都是自动化测试的关键点。但是,这些关键点能否直接套用与安卓应用的自动化测试呢?这些我们将继续在接下来的章节中讨论。

前置条件

这一章我们要开始讨论基于安卓应用的自动化测试。在此之前,我们需要先关注两点安卓系统独有的两大特点:“Root机”与“扰码”。这两点是在上述桌面应用自动化测试中不曾碰到过的。为什么会提及这两点呢?原因很简单,是关乎于安卓应用界面对象的识别。
设备是否需要Root
如果只是为了识别图像或浅层对象,如文本或坐标,测试工具不需要Root权限可以办到。但是对于一些深层次的对象属性,如可见性、宽度、滚动属性等,恐怕要获得系统Root权限才能截获。然而,是否有办法可以绕过系统Root权限能捕捉深层对象属性呢?毕竟,出于各种原因的考虑,Root机的动作不是所有测试人员都愿意做的。安卓系统的设计中规定,两个应用之间是互相独立的,双方各不干涉。不过,如果双方都具备相同的签名,则可互相通信。如此看来,签名像一把钥匙,打开之后,测试工具可以与被测应用通信了。

被测apk的签名与扰码

如果用签名的办法来获取对象,有可能会引入另一个问题:对被测应用的反编译。毕竟,不是所有测试人员都能很容易的拿到代码编译一个测试版本。很多时候,是开发团队打包一个apk交予测试人员进行测试的。所以,要是测试工具与被测应用获得相同的签名,必须先经过反编译之后,设置相同的一个临时签名,再重新进行编译和打包。这样又会引入另一个问题:如果初的apk加入了扰码,导致无法正确反编译怎么办?像签名一样,扰码也是一种保护Android APK的手段之一。遇到这种情况,似乎只能联系开发团队去掉扰码了。
上述两点是因为要抓取被测应用对象而引入的问题。当然,对于界面对象属性要求不高的话,也可以直接截取屏幕图片作为对象,这是这样做,只能通过图像对比的方式来识别对象了。接下来,我们来看看市面上一些现有工具的做法。