基于Robotium自动化测试(上)》一文中小编介绍了框架选择、测试环境搭建、用例编写、跨应用处理等等内容,本文将承接上文,继续介绍测试报告生成、持续集成等等相关内容。
使用Robotium进行自动化测试,测试工程为一个Android Junit Test工程,可以依赖被测工程,与可以选择独立存在。
关联被测工程源码的好处在于可以调用被测工程的代码,因此可以更容易地获取到被测应用内部的状态,例如拿到被测应用ListView内部填充的数据等等。而这样也会带来一些弊端:
(1)测试工程的自动化编译打包也需要关联被测工程,脚本复杂度及维护成本增加;
(2)如果采用R.id.xxx方式获取控件的话,被测工程增加、删除布局文件都可能影响到测试工程的编译结果;
(3)如果被测应用进行了代码混淆,引用被测工程的代码复杂度将大大提高。
鉴于此,应用宝采用的是脱离被测工程的方式,同一份测试apk可以同时测试多个版本的被测应用,另外,即使大家选择有源码的方式,也不建议使用R.id.xxx的方式获取控件。
测试工程需要在AndroidManifest.xml文件中注册instrumentation用于指定被测应用:
<instrumentation
android:targetPackage="com.robotium.android.notepad"
android:name="android.test.InstrumentationTestRunner" />
在同一个测试工程中我们可以只注册一个instrumentation,也可以同时注册多个,例如当被测应用有多个,而测试工程又不想分别建立多个时,则可以使用注册多个的方法。首先,先编写一个继承自android.test.InstrumentationTestRunner的自定义InstrumentationTestRunner,然后同样地在AndroidManifest.xml中注册:
<instrumentation
android:targetPackage="com.robotium.android.anothernotepad"
android:name=".instrumentation.InstrumentationTestRunner"/>
另外,由于许多用例都需要拥有同样的功能特点,例如需要能够进行出错重试与出错截图等等,因此,可以编写一个共有的测试基类,应用宝测试工程中所有的测试类均继承自SingleLaunchActivityTestCase2这个类。
测试用例编写的质量直接关系到用例的稳定性、维护成本以及是否能发现有效问题等等,因此是自动化测试中的关键一环。
首先,是确定测试用例的来源;
当开始准备编写自动化测试用例时,需要确定测试用例的来源,即需要明确例如以下几个方面:
(1)哪些功能是主要功能、哪些功能可以自动化;
(2)用例的优先级、作用的测试阶段;
(3)测试一个功能需要哪些验证点。
不同的项目组需要思考的点可能不一样,但目的是一致的,需要明确测试用例的来源,而不是任意地开始编写用例。应用宝中采用CheckList的形式,通过与各业务线讨论评审的方式确定关键功能、是否自动化、用例优先级、测试验证点等等。
然后,应该合理地去设计自动化测试用例;
在设计自动化测试用例时,除了实现用例来源中的功能步骤外,用例的原子性是需要额外注意的,这将影响到多个用例在一起时是否可以高效稳定地运行。用例的原子性,即指用例间应该保持相对独立,不因用例执行的先后顺序而彼此干拢。
此外,应该以工程的视角去看待测试用例;
测试代码也应该以工程的视角去看待,包括配置管理、结构管理、项目化运作等等。在编写测试用例过程中也应该尽可能地从工程角度在代码易用性、维护性方面去多加考虑。测试代码也应该要有代码规范,包含命名规范、编写规范、注释规范等等,以使测试用例能高效有质量地运转起来。
最后,应该验证测试用例的有效性。
自动化测试用例本身也是需要经过验证与测试的,一个测试用例本身运行通过了并不一定代表用例就是有效的。例如可能因为检查点判断有问题导致该用例始终通过,而一般当用例开始交付运行后,如果一直是通过的,那么往往就不会有人关注,且测试人员会认为该模块已经有自动化测试去保障从而容易忽略基本的测试,所以常常无效的自动化测试用例比没有自动化测试更可怕,需要警惕出现无效的测试用例。在编写测试用例时需要验证用例的有效性,在测试用例交付使用后,也应该定期地关注测试用例的运行情况及其有效性。
(1)传统命令行执行方式
Running alltests: adb shell aminstrument -w com.tencent.assistant.qa/android.test.InstrumentationTestRunner
Running asingle testcase: adb shellam instrument -w -e class com.tencent.assistant.qa.testcase.nuclear.MobileAccelerateTestcom.tencent.assistant.qa/android.test.InstrumentationTestRunner
Running asingle test: adb shell aminstrument -w -e class com.tencent.assistant.qa.testcase.nuclear.MobileAccelerateTest#testMgr_MobileAcceleratecom.tencent.assistant.qa/android.test.InstrumentationTestRunner
Runningmultiple tests: adb shellam instrument -w -e class com.tencent.assistant.qa.testcase.pangu.FoundTabActivityTest,com.tencent.assistant.qa.testcase.nuclear.AssistantTabActivityTestcom.tencent.assistant.qa/android.test.InstrumentationTestRunner
(2)使用spoon执行
java -jar spoon-runner-1.1.3-SNAPSHOT-jar-with-dependencies.jar\
--apk example-app.apk \
--test-apk example-tests.apk \
--class-namecom.tencent.assistant.qa.testcase.common.SearchTest
Options:
--apk 被测APK包所在的路径
--fail-on-failure 当出现failure时,发现非0的退出码
--output 测试报告的输出路径,默认为spoon-output
--sdk Android SDK的路径,若已配置可不填
--test-apk 测试APK的路径
--title 测试报告显示的标题
--class-name 测试用例类名,需要为带包名的全称
--method-name 测试用例方法名
--no-animations 禁止进行截图的gif生成
--size 只运行包含相应注解的用例 (small, medium, large)
--adb-timeout 设置每个用例支持的超时时间(默认为10分钟)
(3)在Eclipse中执行
选择一个测试类后,右键RunAs —— Android Junit Test执行即可。
注:在RunConfiguration中,如设置有多个Instrumentationrunner,则需要指定InstrumentationRunner,如图13所示:
图13.配置Run Configuration
当编写了较多测试用例时,就需要将测试用例分类管理起来,以方便统一维护及用例分级。基于Junit的测试可以使用TestSuite的方式进行管理。
由于在测试执行时,不同的用例执行时间长短不同,且作用的测试阶段也各不相同阶,因此在进行用例管理时,需要明确用例的级别,例如区分是核心功能用例还是普通用例,从而将不同级别的用例放于一处进行管理,在执行时才可以有针对性地进行测试。
Spoon是一个由主导有okhttp、retrofit、leakcanary 等众多优秀开源项目的Square公司在GitHub上的开源项目,志力于改善基于Instrumentation的测试。通过分布式地在多台手机上同时执行基于Instrumentation的测试用例,并且在测试完成后生成统一的拥有测试结果概览、截图、运行时日志等等功能的HTML形式测试报告,Spoon可以更加快速有效地对Android终端进行自动化测试。
项目开源地址:https://github.com/square/spoon
测试采用的Spoon生成,生成报告如图14所示,其中绿条表示用例通过,红条表示用例失败:
图14.报告首页
点击红条可跳转至失败用例的报告详情页,如图15所示:
图15.失败用例的报告详情页
用例采用出错重试并截图机制,当用例失败时进行截图,并往后开启截取一系列运行时的图片,每个用例右边有四个按钮,分别为将截图以gif格式播放、展示多台手机下同一用例运行情况、运行时日志查看、javadoc文档链接。
例如点击右3按钮查看运行时日志,如图16所示:
图16.运行时日志
Spoon会类似单元测试形式的XML报告文件,因此其他测试平台可以通过解析junit-reports目录下的XML报告获取用例执行的详情数据,对每次的测试进行入库存储,积累日常的测试数据,生成历史记录的测试报告页面。
图17 历史数据聚合报告
Jenkins,原名Hudson,2011年改为现在的名字,它是一个开源的实现持续集成的软件工具。官方网站:http://jenkins-ci.org/。
Jenkins 能实施监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性。
7.1.1 参数化构建
Jenkins支持多种参数化构建,如图18所示:
图18.参数化构建
7.1.2 构建前
构建前可关联SVN,设置定时触发器等等常规操作。
此外,安装相应插件后,构建前也可以删除workspace中的指定文件、设置当超时的时候是否停止构建、向workspace事先拷贝文件等等操作。
7.1.3 构建
构建可以增加如图19所示的诸多构建步骤:
图19.构建步骤
常用的有Executeshell(在Linux机器中执行时),用于执行shell脚本;
Execute Windows batch command(在Windows机器中执行时),用于执行bat批处理脚本。
7.1.4 构建后
构建后可以选择如图20所示的构建后步骤,常用的有邮件发送、触发新的构建任务、传递参数等等功能。
图20.构建后步骤
由7.1节可知,Jenkins支持参数化构建、关联SVN、能设定触发时机、支持执行Shell或bat脚本、支持执行后邮件反馈、支持分布式运行等等一系列持续集成的流程。且Jenkins包含丰富的插件可以用于扩展功能,结合实际项目,因此应用宝使用Jenkins来做自化测试的持续集成,整体流程如图21所示。
BVT自动化测试根据不同的分支支持定时触发、分支监控及手动上传三种方式触发测试。任务创建后,将根据所选择的测试节点执行测试,测试用例采用基于Robotium框架编写,测试执行采用基于Spoon框架执行,因此支持在单台手机上执行也支持同时在多台手机上同时执行。测试执行完成后数据报告将回传服务端进行数据处理,数据处理完成将在相应平台上展示数据报告并邮件反馈相关负责人。
图21.整体流程图
定时触发:用于主干每日夜里执行全量用例。
分支监控:用于监控DB分支,当DB分支有新的构建时,就拉取相应apk进行BVT测试。
手动上传:支持各FT及发布分支手动上传apk文件,手动触发BVT测试。
任务创建:任务创建时会将测试工程进行编译打包生成测试.apk,并会将测试工程中需要用到地脚本文件、jar包插件等统一拷贝至服务端的一个根据job名称命名的临时目录。
执行测试:在执行测试前,会将服务端该临时目录下的所有文件push至Slave执行机,然后执行相应的初始化脚本,例如卸载安装应用、清理手机中的残留数据等。
数据处理:在执行测试完成后,执行相应脚本,从手机中pull出测试产物,例如代码覆盖率用的ec文件、性能监控数据、协议日志数据、内存快照文件等。然后使用相应的jar包插件解析测试报告、上传数据至数据库等操作。
邮件反馈:调用邮件模版将测试报告发送指定的收件人。
在这种模式下,BVT测试支持自动执行也支持手动触发执行,在Jenkins中以模版形式既可较灵活地进行配置,且配置维护也较为容易。另外任意能连接成为Jenkins节点的PC都可以迅速成为节点PC机,在节点PC上挂上手机即可成为系统的一部分,可以执行BVT自动化测试任务。