2.1.2 自动化测试框架基本原理
经过前面的一个简单的自动化测试案例,我们对Android的自动化测试有了一个感性的认识,很多有相关工作经验的测试同学也都会理解,这和PC的自动化测试思路是相通的,只不过所借助的框架不同,目前业界已经有很多成熟的开源Android端自动化测试框架,经常用到的框架代表有Robotium和UI Automator,各个框架可能在具体应用上有些不同,如有些偏稳定性,有些适用于Web应用,有些能支持跨应用,等等,但其主要思想是通过控件的位置、名称、属性等获取控件对象,并且对控件对象或者坐标模拟用户操作,测试同学通过这些控件的操作和状态变化来完成自动化测试的执行。图2-4里罗列了目前常用的测试框架,也是本书中实践的重点,后面的章节会详细讨论这些框架的原理及应用。
图2-4 目前常用的测试框架
这一小节讨论的自动化测试框架,是在实际项目中总结出来的且基本能运行的通用基础框架原型,它包括三个核心部分:一是如何获取坐标/控件并操作控件模拟用户端事件,二是脚本中的结果如何判断,三是测试结果报告的输出与展示。不管测试人员使用的是Robotium还是其他框架,万变不离其宗,通用原理都可直接图解为图2-5所示的这几个模块。
图2-5 Android自动化测试基本框架模块
1. 动作执行
自动化测试的首要条件是能够操作控件,最好像开发同学一样操作控件,如何实现呢?一种最常见的脚本录制方法,其主要思想是记录控件的坐标位置和发生的事件,通过回放脚本完成测试事件流,像Monkey Runner框架就提供比较方便的录制回放功能;另一种方法就是通过工具(比如:源码、UIAutomatorviewer等)获得测试界面的控件布局,找到目标空间的ID、名字、描述或者位置信息。测试框架可以通过这些信息得到控件对象,并对控件对象执行一系列事件操作像Robotium、UIAutomater等,这个阶段理解为测试的动作执行。
当然对于有跨应用App的控件操作会受到Android进程安全限制,这对于跨应用的操作是一个难点,举个简单的跨应用例子,在测试一款App应用时,它的某个功能会调起系统相机拍照,那这个功能就会涉及跨应用了。像Robotium就无法调用系统的一些INPUT事件完成跨应用的控件操作(其实Robotium从Android 4.3之后开始支持UIAutomation框架,理应可以支持跨应用的),基于Robotium框架的测试脚本跟被测对象需在同一个App或者可以相互访问,一般要求重新签名打包。所以在选定框架时就需要考虑相关的权限问题,当前可以直接支持跨应用的框架有MonkeyRunner、UIAutomater等, 后面的章节会详细给出主流框架的分析和使用建议,这里不再细述。
2. 结果判断
自动化测试中非常重要的一个环节就是测试步骤的验证,如何能不进行人工干涉而去正确并且自动地检查验证点,这是自动化测试环节中的一个关键点,有些可以借助测试框架的截图对比(像MonkeyRunner)直接完成结果输出,但在实际项目中会有很多具体业务,验证点会比较困难,不同的案例可以用拆解和辅助的验证方式来完成。比如播放器播放视频时,如何验证视频播放成功,这里就需要设定很多验证点。若播放的时间≥0,可以直接获取video标签里的current time来判断;若是功能测试,则有两种情况:①播放时有画面,可以直接截屏获取;②播放时有声音,可以获取声卡捕捉声音的数据,分析波形文件,但实现起来难度就比较大,后面的章节中有具体的案例介绍。基本结果验证的方法概括如下。
(1)截图对比。对于GUI的测试,一般会采用截图方式,但最简单的截图也需要考虑到很多附带的条件,大部分框架会有此功能(没有的话也不要紧,可以直接用系统自带的screencap或者其他工具配合使用),但它每秒能截取多少张图片?能否满足我们需要的图片判断条件?截取的图片如何做对比,对比的参照物是什么?做性能测试时,我们的工具是否会影响性能?要不要选择拍照工具而不影响性能?获取图片的速度能否满足性能测试要求?对比的参照物又如何设定?这些信息在每个具体的案例中又会衍生一系列新的问题。就一个具体的案例来说,浏览器打开网页的首字响应时间测试中,对比参照物可以是一张空白的图片,把指定的像素区域与这张空白图片做对比就能判定结果;而浏览器播放视频时的响应时间测试时所截取的图片,就不能这样判断,因为很多视频会在播放之前就显示一个关键帧的图片。为什么会这样?本书后面的章节会针对一些典型业务进行由浅入深的案例分析与工具设计,会用到基本框架但不局限于此,还需要测试人员更多的对工具和框架的配合应用与改造能力,完成系统性的业务测试需求。
(2)控件对比。Android UI自动化测试最直接面对的是应用程序界面,界面上存在按钮(button)、文本框(textView)等,我们都称之为控件。有些应用程序的执行逻辑直接体现在控件的状态显示上,如按钮状态的变化、文本的改变等。常用的自动化测试工具Robotium和UI Automator都提供了获取应用控件的接口, 当执行完一定的自动化测试逻辑后,可以将获取控件上的信息与预期的信息进行对比,判断测试结果是否通过。比如测试一个计算器程序,执行3乘以5的测试用例后,可以在结果输出框得到输出的值(result),用框架的结果与预期的结果做对比:assertEqual(result, 15),判断这个测试用例的结果是否通过。
(3)日志分析。日志分析可以作为一个辅助结果判断,比较适合在集成测试阶段做的一些接口、稳定性和性能测试,因为这个阶段产品的日志一般处于打开状态,测试同学可以很方便地收集到日志关键字信息。比如在进行稳定性测试时,可以直接把所有日志输出至文件,在测试执行程序中加入简单的文本处理,对日志信息进行分类检索,像在Java层出现 crash时,可以搜索日志中的FATA EXCEPTION/ANR等关键字,提取后面的几十行日志信息进行筛选处理。日志使用的更高进阶是日志埋点,对需要测试的接口埋入上报信息,一旦测试执行(用户使用)到该点,启动上报接口(或者SDK)送至指定的路径,就可以直接准确地看到测试结果,一般在灰度发布后这些日志信息会被关闭,总体上不会影响产品的功能。但日志的使用也有一些局限性,比如测试同学对日志tag不熟悉,需要先了解代码信息等,还有竞品对比测试时因为拿到的竞品包都是混淆的正式发布包,没有关键日志信息输出,可能需要用其他的手段来判断结果,比如控件对比(当然高手例外,他们可能会使用逆向工程,反编译再注入需要的log)。
3. 报告展示
报告展示一般是指给出整个测试的结果信息汇总并进行简单的分析,测试结束后直接输出预警和初步的数据报告,以邮件或者其他形式直接周知项目参与人员。如果执行较大的项目测试,就可能需要多维度、多指标地对待测应用的测试数据进行整合,要求测试同学对平台有较高的设计能力,比如平台需要实现产品中核心业务的性能benchmark测试结果及分析,BVT(Build Verify Testing)测试中发现的问题预警,功能自动化测试脚本中的BUG自动提单,等等。有些自动化测试框架里也带有简单的测试管理平台,根据业务类型决定这些平台是否能满足需求,有的产品需要平台支持多业务的横向与纵向对比信息、竞品的评分信息等,这时就需要做二次开发,形成一个系统性的测试管理工具,也即前文中说的测试的管理平台框架