本篇开始将介绍几个重量级的测试框架,首先介绍的是Android最早推出的便于进行程序深入的,系统性的单元测试的框架–Instrumentation。
Instrumentation从android2.3甚至更早版本就存在了,很多Android自动化测试框架都是对于Instrumentation的直接使用或二次开发,例如:Robotium。
在学习Instrumentation之前,先了解一下Junit,作为一款成熟的单元测试框架,Junit的目的非常明确:通过该框架可以为被测代码编写相应的测试代码,快速定位错误,节省调试时间,最终提高代码健壮性。
在测试Android程序时,也可以使用Junit进行测试,但是有前提条件,测试的case中不能存在Android的API相关的测试用例,也就是说只能包含Java层相关的测试。
因为在Junit设计初期,不可能考虑到Android系统的各种要求,但是一个Android应用自然会包含各种控件,activity,service等Android自身特有的东西,而要将Junit的思想应用到Android系统上,就必须针对Android系统的各种要求对Junit进行扩展,进行二次封装。Instrumentation也就应运而生。
Instrumentation 是Android SDK在Junit上的扩展,提供了AndroidTestCase类及系列子类,其中一个最重要的类是ActivityInstrumentationTestCase2;
使用Instrumentation测试时,需在测试类中继ActivityInstrumentationTestCase2。
然后重写几个方法,setUp(),tearDown();
而测试的用例,要命名为void testXXX()格式,将测试的过程填充到此方法中。
ActivityInstrumentationTestCase2允许测试类TestCase.launchActivity来启动被测试的Activity。
而且ActivityInstrumentationTestCase2还支持在UI线程中运行测试方法,并能注入intent对象到被测试的Activity中,这样就可以直接操作被测试的Activity了。
举例:在被测试的应用程序中,有一个Button,一个Edit和一个TextView,主要的工作就是在EditText中输入文本,点击Button之后,在TextView中显示。
我们如何写个测试Case来测试这个功能呢?首先要先启动Activity,获取这个被测Activity实例,其次在setUp()中获取到上述的几个控件,与开发过程相同;最后命名一个testXXX()用例,在此方法中先在EditText中setText,然后在Button方法中,获取EditText内容,再setText到TextView中;进行验证,TextView中是否显示EditText设置的内容。如果测试成功,整体流程在tearDown()运行之后结束。
思想上很好理解,就是通过事件注入的方式,实现应用程序的一系列自动化操作,然后进行结果的验证。
总结一下,Instrumentation框架的运行流程:
(1)启动应用Activity:Intent
(2)获取Activity实例:Instrumentation
(3)过去Activity中控件的实例:findViewById
(4)执行控件的操作
(5)验证是否为预想情况
分析:
优点:
- Instrumentation是基于项目源码进行开发
- 测试脚本的稳定性好(控件ID改动较少)
- 可移植性好(基于控件ID,而不是像素点)
- 运行效率高(直接调用控件进行操作)
- 调试方便(可配合源码一起调试)
缺点:
对脚本开发人员要求高,要熟悉Java语言,Android框架运行机制等,难以上手
最大的问题是不支持多应用交互,因为测试脚本与被测App运行在同一进程中,而Android系统自身不允许进程间相互访问,无法直接启动另一个进程的Activity,只能定义Intent(隐式),然后由系统选择能够处理这个Intent的Activity。
Instrumentation为我们开发自动化测试框架提供了一个基础的原型,在开发过程中,很多功能就是根据Instrumentation进行的开发和二次封装。
而为了解决跨进程的问题,Android提供了另一个测试框架,UIAutomator,后文将继续介绍。