摘要
桌面应用程序与浏览器端的自动化测试都已经历了十年的发展,无论是从工具上还是项目管理方法论上都已经趋于成熟。而移动设备端应用程序的自动化测试近两年才刚起步,似乎一切尚处于探讨与研究阶段。但我们似乎已经看到其爆炸性的需求增长势头。可以从这两方面着眼分析:其一,移动应用从数量上和逻辑复杂程度上的增长,以及产品发布周期的紧缩,使得快速回归测试迫在眉睫;其二,安卓系统的开放性造成硬件厂商百家争鸣的局面,设备款式之多,迫使移动应用的兼容性测试提上日程。纵观当前智能手机两大主流阵营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的手段之一。遇到这种情况,似乎只能联系开发团队去掉扰码了。
上述两点是因为要抓取被测应用对象而引入的问题。当然,对于界面对象属性要求不高的话,也可以直接截取屏幕图片作为对象,这是这样做,就只能通过图像对比的方式来识别对象了。接下来,我们来看看市面上一些现有工具的做法。
工具
目前市面上的安卓测试工具主要分为三种类型:
- 通过界面图像的对比识别对象 – 这类工具的代表是以色列的PerfectoMobile.com。这是一款纯Web操作方式的工具,可以支持测试脚本跨平台执行;
- 通过在源码级识别对象 – 这类工具的代表是芬兰的TestDroid.com。它是以Eclipse Plug-in的方式工作,可以将录制的操作步骤生成Robotium或MonkeyRunner脚本;
- 通过数字签名识别对象 – 这类工具的代表是DroidPilot.com。它可以说是高度模仿HP QTP的操作方式,对于自动化测试工程师来说,也许会有似曾相识的感觉;
接下来,我们准备从以下几个方面剖析这三类工具对于关键字驱动自动化测试的支持:
- 与被测apk的通信 – 捕获对象、控制行为
- 脚本编辑器 – 构建测试脚本、解析测试脚本
- 并发控制多台设备 – 脚本一次编译,可跨设备执行
- 与其它测试工具的整合 – 测试用例管理、缺陷跟踪
1. 与被测apk的通信 – 捕获对象、控制行为
首先来看PerfectoMobile。这款工具是纯Web操作方式。它对应用程序界面对象的识别是通过图像对比来判断,所以严格来讲,这并不能称之为“对象”。但不得不承认,这种做法使得跨平台(iOS, Android, Blackberry…)的对象识别成为可能。同样道理,即是从图像来识别对象,也是通过图像来操作对象。当对象库中的该图像在当前屏幕的对比匹配率达到一定程度,即可认为找到了该对象,从而也就可以对相应区域进行点击、滑动等操作了。
另一种是TestDroid的做法,直接从代码级截获对象。在Eclipse开发工具装上TestDroid插件,直接点击录制按钮,即可启动被测应用。所录的操作步骤,可以生成Robotium或MonkeyRunner脚本(注:Robotium和MonkeyRunner是Android平台最流行的两款开源测试工具)。这种直接在代码级操作的做法,尽管能毫无阻拦的拿到任何想要的对象信息,但是也有几点待商榷之处:1. 对于测试工程师直接来到代码级进行操作,从代码安全性考虑,这并不是对于所有企业都可行;2. 这种做法仅限于Android应用,不能做到像图片识别那样跨平台。当然,对于iOS引用来说,是否需要花力气去做自动化测试,还是可以商议的,毕竟它的设备种类不太多,省去了许多兼容性测试的成本。
第三种是DroidPilot的做法,即上面《前置条件》章节提到的通过签名模式与被测应用取得通信。这种做法虽然也是仅限于Android平台,但毕竟可以抛开源码,更贴近于测试工程师的工作行为。然而,正如所提到的,这种做法难免遭遇“扰码”的阻碍。所以,用这种方式做自动化测试,必须要求被测应用不能加任何扰码信息。其实这里还有一点是关于反编译之后,被测应用的行为是否会发生改变的问题。这里可以确定的是,由于反编译之后,仅仅是改变了被测应用与测试工具之间的临时签名信息,对于被测应用压缩包中的信息并无任何改动,所以,被测应用的行为是可重复、可验证的。
2. 脚本编辑器 – 构建测试脚本、解析测试脚本
对于PerfectoMobile,由于它是以纯Web方式操作,即脚本的编辑和执行都是在浏览器端操作,这样可以让客户免于安装客户端。他在Web端提供了一种脚本设计器,可以通过拖拽设备模拟按键(如打电话,发短信,音量键、返回键等)到设计窗口,编排顺序以产生测试用例。近年PerfectoMobile又提供了HP QTP插件,使用户可以用QTP来制作脚本,并把做好的脚本上传到他们的网站,借助他们的设备来执行脚本。所以,这款工具的脚本构造能力还是相当强大的。而且,由于与QTP结合,使得自动化测试工程师更能平滑的从桌面应用程序自动化测试过渡到移动应用自动化测试。
TestDroid则通过流行的开源工具Eclipse作为脚本编辑器。它以Eclipse插件的形式存在。通过该插件来录制脚本、回放脚本。录制的脚本可以生成Robotium或MonkeyRunner脚本语言。这些脚本语言对于开发工程师来说也许会很熟悉,因为有不少安卓开发工程师自己也会用这些工具来制作一些简单的自动化测试脚本用于每日脚本构建(Daily Build)后的冒烟测试(Smoke Test)。对于测试工程师来说,上手这类Jave或Python语言视乎要比QTP所用的VB Script要稍微吃力一点,且对于Eclipse这类开发工具的使用熟练程度也不及QTP。尽管如此,对于在语言和工具的学习曲线这方面的开销,比起日后Eclipse所能提供的强大而灵活的脚本编辑能力来说,应该也是值得的。
DroidPilot则是完全自己开发的脚本解析器,选用的语言也是VB Script。而且它也提供了一种脚本设计器,这种设计器可以通过点选界面对象和针对对象的操作,来构建测试流程,并把设计好的测试流程转换成为脚本语言。这种设计器虽然可以快速构建简易的测试流程,但是对于复杂一点的测试逻辑,还需要测试工程师自己在脚本中完善。但无论如何,这个动作已经大大简化了测试工程师的代码量,且操作效率甚至比录制更灵活,因为它可以在任意操作步骤之间增加或删减步骤,且能调整操作步骤的前后顺序。
3. 并发控制多台设备 – 脚本一次编译,可跨设备执行
PerfectoMobile号称拥有市面上所有智能手机(iOS, Android, Blackberry…),而且这些手机部署在全球不同国家。用户登录Web控制台后,可以对这些手机进行任意操作:打电话、发短信、安装/卸载被测应用等。它不但等做到测试脚本跨设备执行,甚至还可以跨平台执行,因此,可以说,他在兼容性测试方面还是考虑的比较全面的。然而,似乎有一点遗憾的是,制作好的脚本并不能并发的在多台设备上执行,而是需要手工选择设备执行。而且,对于被测应用的部署也是一样的,缺乏批量部署这样的功能。这可能限制了并发性兼容性测试的工作效率。
TestDroid由于是使用Eclipse插件形式工作,这个插件在录制和回放脚本的时候同一时间只能链接一台机器。尽管这样做对于脚本的编辑和调试来说已经够用了,但还无法满足批量设备的兼容性测试。因此,他们又额外开发了一个在线平台,用户只需要将开发好的脚本和被测应用上传到他们的服务器,这些应用和脚本就会被自动部署于服务器端的大量安卓设备,并执行测试。最后,用户会收到兼容性测试报告。
DroidPilot有专门的脚本编辑工具Script Designer,而且这个工具也是限定了只能连接一台设备进行脚本编辑和回放。如果需要连接多台设备进行兼容性测试的话,就需要用到DroidPilot的另一款工具——AutoRunner。通过这款工具 ,用户可以将多个脚本在多台设备上执行回放,还可以设置按设备顺序回放,还是多设备并发回放。并且还能自定义回放起始时间。
4. 与其它测试工具的整合 – 测试用例管理、缺陷跟踪
PerfectoMobile在Web端是没有整合任何测试管理工具的,纯粹是提供设备给用户使用,用于制作测试脚本和回放。近年由于新开发的QTP Plug-in,使得它能借助HP测试管理工具Quality Center用于管理测试脚本和跟踪缺陷。
TestDroid由于走的是开源工具路线,可以借助Eclipse的相关插件来达到管理测试脚本的效果。例如,使用Eclipse的svn插件,可以使得脚本保存于svn数据库,有利于测试团队协同工作。但是对于缺陷跟踪管理这一块,似乎还没有明确的工具整合进来。
DroidPilot在设计之初就考虑到了与一些开源测试管理工具的整合,例如,用TestLink作为测试用例管理,用Bugzilla/Mantis作为缺陷管理工具。因此,DroidPilot提供了与这些开源工具之间对接的http协议接口。
实践
探讨完上述关于不同测试工具的使用特点,更准确的说,是安卓应用自动化测试工具的特点,我们不妨来实践(其实是模拟)一个移动应用的测试过程。这里我们选用API Demo作为被测应用,选用DroidPilot作为测试工具。
分析被测应用
被测应用API Demo 使用标准Android SDK作为开发控件,且被测应用未加扰码,因此,界面上所有元素可以被DroidPilot识别。
对于一些非标准Android SDK控件开发的应用,这里有两种情况:一种情况控件完全由自己开发,如果是这种情况,DroidPilot完全无法识别对象;另一种情况是在标准控件基础上做了二次开发,这样的话DroidPilot只能识别到原生SDK那一层。对于这两种情况,都可以联系DroidPilot开发团队为非标准控件度身定制专属插件,用于识别被测控件。
对于扰码问题,正如上述《前置条件》章节所描述的,DroidPilot本身是无能为力的,只能请开发团队去掉扰码,打包一个不加扰码的测试包给测试团队使用了。
设计测试用例
这里我们假设一个测试用例是进入\App\Activity\Animation\Fade in\界面,对界面的元素(按钮、文本框、多选框、单选框、下拉列表)进行操作,并验证文本框的文字是否符合我的预期结果。测试步骤如下:
测试用例1 - 验证\App\Activity\Animation\Fade in\界面元素 |
||
前置条件:API Demo已经启动,停留在起始页 |
||
步骤 |
动作 |
期望结果 |
1 |
点击App项 |
|
|
点击Activity项 |
|
|
点击Animation项 |
|
|
点击Fade in项 |
|
|
在文本框输入"put your text here" |
|
|
勾选Checkbox1 |
|
|
向下滑动一次屏幕 |
|
|
点击下拉框 |
|
|
勾选Venus |
|
|
检查文本框 |
文字="textColorPrimary" |
开发测试脚本
先使用DroidPilot脚本编辑工具抓取各个屏幕的对象,然后把这些对象选入脚本设计器,按照测试用例的顺序来排列,如下图:
然后DroidPilot会根据设计器的内容自动转变成脚本代码,如下图:
在这个用例中并没有设计复杂逻辑,所以无需在脚本中添加如If…Else之类的判断语句。
运行及维护
使用脚本编辑器可以连接一台设备,用于调试测试脚本。但是如果需要将测试脚本同时运行于多台设备进行兼容性测试,就需要用到DroidPilot的另一款工具AutoRunner。通过它,用户可以同时选中多个脚本,并在多台设备上执行。而且用户也可以控制脚本的执行起始时间,使用户可以定时执行脚本。
更多考虑
在以上的章节中,我们的着眼点都是在工具和技术上的讨论。但是对于真实的移动应用测试项目,一旦引入自动化测试,必然需要考虑对整体进度、项目成本的影响。所以,这里就会有以下考虑:
评估自动化工具的引入对现有项目进度的影响
对于传统项目,如果在前期就已经有自动化测试的规划,项目经理手上应该有足够的资源调配自动化测试工程师,使得他们可以是一个独立于手工测试之外的团队,这种做法并不会对项目进度产生太大影响。但是对于移动应用测试,通常的项目周期都会比较短,而且测试团队的成员数量不足以额外的配备专门的自动化测试工程师,很可能是一些手工测试工程师挤出时间来做一些小量的自动化测试脚本,用于版本发布时的快速冒烟测试。这种花在自动化测时间上的比例,相比于本来就不是很长的测试周期,也许就会显得特别突出。
团队工作模式的变化
如果如上所言,只是手工测试工程师挤出时间来做一些小量的自动化测试脚本,用于版本发布时的快速冒烟测试,那对于自动化的整体效果来说并不见得有很大帮助。至少对于目前大部分安卓开发项目来说,很少见到投入一至两位专职自动化测试工程师来做这类事情。但是,如果考虑到将来频繁的版本发布,以及安卓应用独有的海量的兼容性测试,对于自动化的前期投入还是显得有必要的。
如下图,传统模式,测试工程师可能在第一轮测试才有一次Full Test, 在后续的回归测试中,可能只能做到部分回归。
如果引入自动化测试工程师,同步开发测试脚本(理想情况,每个应用自动化比率达到70%~80%, 整体自动化比率达到60%~70%),有可能使得回归测试比率有所提高。
从零做起
既然如此,何不从现在开始,从零开始,在项目中尝试引入自动化测试,哪怕只是抽调部分人力着手部分应用的自动化测试,至少可以达到Daily Build Smoke Test的效果。再者,移动应用自动化测试行业正处于起步阶段,此时介入也不失为一个好时机。
结论
回顾上述讨论的内容,我们设想能在移动应用自动化测试领域延续桌面系统自动化测试的成功经验,从理论基础、工具支持、以及后续项目管理方面都做了一番探讨。尽管主要还是局限于安卓应用的自动化方面,对于iOS提及较少。不难理解,iOS本身支持的机型有限,对于设备兼容性测试并不是重点关注的内容。而在功能性回归测试方面,它本身也有相关工具支持。至于像Blackberry之类的平台,因为本身并没有呈现爆炸性的应用增长,所以也没有列在讨论范围。所以,本文仍以安卓平台作为自动化测试的突破口,希望从中能结合市面上的一些商用工具,尝试实践以“关键字驱动”为基础的自动化测试,而非原始的以“坐标点”为基础的屏幕点击测试。对于开源工具也没有提及,原因是考虑到像Robotium和MonkeyRunner之类的流行工具可能更贴近于开发工程师使用,而非更贴近于测试工程师。所以,我们希望在上述的讨论中能带给读者在测试项目中新的启发。
参考资源
- 维基百科 “关键字驱动测试(Keyword-driven Testing)” - http://en.wikipedia.org/wiki/Keyword-driven_testing
- 安卓“信任应用(Trusted Process)” - http://developer.android.com/guide/topics/security/permissions.html
- 安卓“Root权限” - http://en.wikipedia.org/wiki/Rooting_(Android_OS)
- 商业工具TestDroid(芬兰) - http://testdroid.com/
- 商业工具PerfectoMobile(以色列) - http://www.perfectomobile.com
- 商业工具DroidPilot(中国) - http://www.droidpilot.cn/
- 开源工具Robotium(美国) - http://code.google.com/p/robotium/
- 开源工具MonkeyRunner(美国) - http://developer.android.com/tools/help/monkeyrunner_concepts.html