测试与指令(Instrumentions)
Android
包含了一组丰富的测试工具,它针对Android
环境扩展了行业标准的JUnit
测试框架。你仍可以使用JUnit
测试你的Android
应用,但是Android
工具却允许你写出更加精密复杂的测试你的应用的每个方面,不论是单元测试还是框架层次的测试。
Android
的测试环境包含以下关键功能:
Android
对JUnit
框架的扩展,通过了访问Android
系统对象的功能。
指令框架可以使测试代码控制并检查应用
模拟常用的Android
系统对象。
提供了运行当个测试或一组测试的工具,可以使用指令也可以不使用
支持通过命令行或Eclipse
的ADT
插件管理测试用例及测试工程。
本文概述了Android
测试环境以及它的使用方法。本文假设你了解Android
应用编程及JUnit
测试方法的基础知识。
概述
Andorid
测试环境的核心是指令框架,使用它在测试时你可以精确地控制程序。使用指令,你可以在主程序启动前建立模拟的系统对象如Context
,可以控制程序的生命周期,可以像应用发送UI
时间,可以在应用运行时检查它的状态。指令框架通过使主应用和测试应用运行于同一个进程来实现这些功能。
在测试应用的manifest
文件中定义<instrumentation>
元素,可以使测试应用在测试时连接到主应用。这个元素的属性指定了主应用的package
名字,并告诉Android
如何运行测试应用。关于指令的更加详细的描述请参考Instrumentation Test Runner
。
在Android
中,测试应用是Android
应用本身,因此,编写测试应用的方式与被测应用的一样。SDK
工具帮你创建主程序的工程的同时也创建它的测试工程。你可以通过Eclipse
的ADT
插件或者命令行来运行Android
测试,也可以使用adb
工具或者内置的Ant target
运行测试。
如果希望一份手把手的Android
测试介绍,请尝试一下的测试例程:
Hello
,Testing
例程以Hello, world
应用为例介绍了基本的测试概念和程序。
Activity Testing
例程比Hello, Testing
例程更加深入。它指导你在一个更加真实的应用中开发一个更加复杂的测试场景。
测试API
为了使用JAVA
编写测试级测试应用,Android
提供了一套扩展自部分JUnit
测试框架的测试API
。除此之外,Android
提供了强大的指令框架,它允许开发人员的测试代码访问应用的状态以及运行时对象。
以下章节描述了Android
中可用的测试API
的主要部件。
JUnit
测试用例类
测试API
中的一些类扩展了JUnit
的TestCase
类,但是没有使用指令框架。这些类包括测试中访问系统对象的方法,比如程序的上下文Context
。使用Context
,开发人员可以查看资源,文件,数据库等等。基类是AndroidTestCase
,通常使用一个与特定部件关联的子类。
这些子类是:
ApplicationTestCase:
用于测试整个应用。它可以注入一个模拟Context
到应用中,在程序启动前设置初始的测试参数,以及在应用结束后销毁前检查相关数据。
ProviderTestCase2:
用于独立地测试单个的ContentProvider
。因为限制使用模拟的MockContentResovlver
,并且注入一个独立的IsolatedContext
,使得这个provider
测试独立于操作系统的其余部分。
ServiceTestCase
:用于独立地测试单个的Service
。开发人员可以使用它注入一个模拟的Context
或者更模拟的应用(或者两者都注入),或者要求Andorid
提供一个完全的Context
和一个MockApplication
。
指令测试用例类
这些测试activities
的API
扩展了JUnit TestCase
类,并使用了指令框架。使用指令, Android
可以向测试中的应用程序发送时间进行自动化的界面测试,可以精确地控制activity
的启动,以及在activity
的整个生命周期中监测它的状态。
基类是InstrumentationTestCase
。它的所有子类都可以向测试应用发送键盘敲击时间和屏幕触摸事件,也可以注入一个模拟的Intent
。
这些子类是:
ActivityTestCase
:activity
测试用例的基类。
SingleLaunchActivityTestCase
:用于测试单个的activity
。它仅调用一次setUp()
和tearDown
,而非每次方法调用就调用一次。在同一个activity
上测试所有的方法时可以使用这个类。
SyncBaseInstrumentation
:用于测试content provider
的同步操作。它可以使用指令在开始被测同步操作前取消或禁止已经存在的同步操作。
ActivityUnitTestCase
:用于独立测试单个的activity
。使用它,可以注入一个模拟的上下文或应用或者两者都模拟。
与其它指令类不同,这个测试类不会注入一个模拟的Intent
。
ActivityInstrumentationTestCase2
:这个类用于在正常的系统环境下测试单个的activity
。你不能注入模拟的Context
,但可以注入模拟的Intent
。同样的,你可以在UI
线程(被测程序的主线程)中运行测试方法,这允许你向应用界面发送按键与触摸事件。
断言类
Android
同样也扩展了JUnit
的Assert
类,这是测试代码中assert()
的基础。这个类有两个扩展MoreAsserts
和ViewAsserts
:
MoreAsserts
包含了更加强大的断言,例如支持正则表达式匹配的assertContainsRegex(String,String)
。
ViewAsserts
包含了用于Android Views
的断言,例如只可以检测在屏幕的某个位置是否存在某个View
控件的assertHasScreenCoordinates(View,View,int,int)
。这些断言简化了UI
的形状位置和排列的测试。
Mock
对象类
Android
提供了创建模拟的系统对象,例如应用程序、上下文、content resovlers
和resources
。Android
也提供了一些创建模拟Intent
的测试类。这些对象使依赖关系注入更加容易,因为使用它们比创建真实的对象简单。这些类定义在android.test
和android.test.mock
中。
IsolatedContext
:模拟了一个上下文,应用程序使用它可以独立运行。同时,它还有足够的桩代码来处理与上下文通信的OS
代码。这个类用于单元测试。
RenamingDelegatingContext
:当一个已经存在的普通上下文改变它的默认文件和数据库名时,将大多数上下文的功能委托这个上下文。这样可以使用一个普通的系统上下文和测试名称测试文件和数据库操作。
MockApplication,MockConentResolver,MockContent,MockDialogInterface,MockPageManager,MockResource
:测试中使用的创建模拟系统对象的类。它们仅仅暴露那些用于管理对象的接口。这些方法的默认实现是简单的抛出一个异常。当测试应用调用这些方法时,你应该扩展这些类并覆写这些方法。
指令测试执行器
Android
提供了一个定制类用于运行带有指令调用的测试,叫做InstrumentationTestRunner
。这个类控制测试中的程序,在同一个进程中运行测试程序以及主程序,并将测试输出发送到适当位置。InstrumentationTestRunner
在运行时控制整个测试环境的关键是指令的使用。注意,即使在你的测试类中没有使用指令,也会使用这个测试执行器。
当你运行一个测试程序时,你首先运行系统组件Activity
管理器。它使用指令框架启动和执行测试执行器,测试执行器反过来使用指令关闭所有运行的主程序的实例,启动测试程序,然后在同一进程中启动启动主程序。这允许测试程序从不同的角度与主程序交互。
如果你使用Eclipse
开发,ADT
插件可以帮助你设置InstrumentationTestRunner
或其它测试执行器。插件会提示你指定使用哪个测试执行器和被测试应用的package
名称,插件会自动添加一个<instrumentataion>
元素到测试程序的manifest
文件,并填充适当的属性。Eclipse
的ADT
插件会自动在使用指令的Activity
管理器的控制下启动测试应用,并将测试输出重定向到Eclipse
的JUnit
视图窗口中。
如果你使用命令行,你可以使用Ant
和android
工具帮助你设置你的测试工程。可以使用adb
工具访问Activity
管理器运行带指令的测试,并将输出定向到标准输出上。
使用测试环境
测试程序包含了对一个Android
应用的测试代码,它本身也是一个Android
应用。测试应用存放于一个独立的Android
工程中,它和标准的Android
应用一样拥有文件和目录。测试程序通过它的manifest
文件链接到被测应用。
每个测试应用包含一个或多个测试用例类,它们派生于特定类型组件的Android
类。这些测试用例类包含了一些方法,它们定义了对被测应用的某部分的测试。当你运行测试应用,Android
会启动测试应用,加载被测试应用到同一个进程中,然后调用这个测试用例类中的每个方法。
测试所需的工具和流程取决于你使用的开发环境。如果你使用Eclipse
,ADT
插件会提供工作帮助你开发和运行测试。请参考主题
Testing in Eclipse, with ADT。 如果使用其它开发环境,你需要使用命令行工具,请参考
Testing in Other IDEs 。
使用测试工程
要开始测试一个Android
应用,你要使用Android
工具为它建立一个测试工程。工具会建立工程文件夹和需要的文件和子目录。工具也会建立一个连接到被测试程序的manifest
文件。使用Eclipse ADT
插件建立测试工程的步骤在
Testing in Eclipse, with ADT 中有描述,使用其它开发工作的步骤描述在文档
Testing in Other IDEs中。
使用测试用例类
一个测试应用包含一个或多个扩展自Android
测试用例类的测试用例类。选择哪个测试用例类,取决于你要测试的Android
组件的类型和要测试的内容。一个测试应用可以测试不同的组件,划每个测试用例被设计成只能测试单个类型的组件。Android
测试用例类的描述在章节
The Testing API 中。