android activity 测试,android中文SDK--Activity测试

activity测试

activity测试依赖于Andreoid instrumentation框架。不像其他组件,activiy具有复杂的基于回调方法的生命周期,这些方法不能直接调用,却可以通过instrumentation来调用。同时,从一个程序向用户界面发送时间的唯一方法就是通过instrumentation。

本文档介绍如何使用instrumentation和其他测试工具测试activity。文档假定你已经阅读了测试基本原理,android测试和instrumentation框架的介绍。

activity测试API

activity测试API基类是InstrumentationTestCase,它为你使用的activity测试用例子类提供instrumentation。

对于activity测试,这个基类提供了以下功能:

l

生命周期控制:通过instrumentation,你可以使用测试用例类提供的方法来启动、暂停和销毁要测试的activity。

l

依赖注入:Instrumentation允许你创建虚拟系统对象如Contexts或者Application,并使用他们来运行测试activity。这使得你可以控制测试环境并且将它与系统分离出来。你也可以建立自定义的Intents并用他们启动activity。

l

用户界面交互:使用instrumenta直接向activity的UI发送键盘输入或者触摸事件。

activity测试类通过扩展TestCase和Assert来提供JUnit框架支持。

两个主要的测试子类是ActivityInstrumentationTestCase2和ActivityUnitTestCase。用SingleLaunchActivityTestCase来测试不是以标准模式启动的activity。

ActivityInstrumentationTestCase2

ActivityInstrumentationTestCase2测试用例类被设计用来进行一个应用程序里的一个或多个activity的功能测试,使用的是标准的系统配置。他在一个标准的应用程序实例里运行activity,使用的是标准的系统Context。它允许你向测试的activity发送虚拟Intents,因此你可以用它来测试activity对不同类型intents的响应,或者测试acivity对于intent里特定类型数据的响应,或者对这两种情况两者同时进行测试。但是请注意,他不允许虚拟Context或者Application,所以你不可以将测试从系统中独立出来。

ActivityUnitTestCase

ActivityUnitTestCase测试用例类独立的测试一个单独的acticity。在你启动该activity前,可以注入一个虚拟Context或者Application或者同时注入两者。你用它来独立运行测试,并且不通过与Android交互而去进行单元测试。你不能向测试的activity发送虚拟Intents,但是你可以调用Activity.startActivity(Intent)方法,然后查看接收到的参数。

SingleLaunchActivityTestCase

SingleLaunchActivityTestCase类对于在一个没有改变的环境中测试单独的activity是很方便的。他只调用一次setUP()和tearDown()方法,而不是测试方法都调用。他不允许你注入任何虚拟对象。

虚拟对象和activity测试

该部分包含了在activity测试中使用andorid.test.mock中定义的虚拟对象的一些注意事项。

虚拟对象MockApplication只有在你使用ActivityUnitTestCase测试用例测试activity的时候才可用。默认地,ActivityUnitTestCase创建一个隐藏的MockApplication对象作为测试的application。你可以用setApplication()方法注入你自己定义的对象。

activity测试的断言

ViewAsserts为Views定义了断言。你用它来验证View对象的几何图形和坐标,并且查看ViewGroup对象的状态。

测试什么

l

输入验证:测试activity正确地响应TextEdit View的输入值。建立一个按键输入序列,发送到activity,然后用findViewById(int)来检查View的状态。你可以当输入序列正当有效时让一个OK按钮变成可用状态,当输入序列无效或非法时让按钮不可用。你也可以通过在View中设置错误信息来验证Activity对于无效输入的响应。

l

生命周期事件:测试应用程序的每个activity正确的处理生命周期事件。通常地,生命周期是来自系统或用户的actions,触发回调方法如onCreate()或onClick()。例如,activity应该在响应暂停或销毁事件的时候保存它的状态。记住甚至屏幕方向的改变都可能引起当前activity的销毁,所以你应该另外测试设备改变不会意外地丢失应用程序状态。

l

Intents:测试每个activity正确地处理配置文件中列出的intent filter。你可以用ActivityInstrumentationTestCase2来发送虚拟intent到测试的activity中。

l

运行时配置变化:测试每个activity在设备可能发生的改变时正确的响应。这包括设备方向的改变、当前语言的改变等等。处理这些改变在“处理运行是改变”主题中有详细说明。

l

屏幕大小和解决方案:发布应用程序前,确认在你想要运行的所有屏幕大小和密度下通过测试。你可以使用AVDs来测试应用程序在多种大小和密度下的运行,或者你可以直接在目标设备上测试。更多信息,参看“支持多屏幕”主题。

附录:UI测试注意事项

以下部分是测试Android应用程序UI的一些技巧,帮助你处理在UI线程中运行测试、触摸屏和键盘事件、测试中home屏幕解锁等。

在UI线程中测试

应用程序的activity运行在应用程序的UI线程。一但UI被实例化,例如在activity的onCreate()方法,然后所有与UI的交互必须运行在UI线程中。当你正常地运行应用程序他就已经进入了该线程,不需要做另外的事。

当你测试应用程序时会改变这种情况。当使用基于instrumentation的类测试时,你可以违反UI去调用方法。其他测试类则不允许这样做。为了在UI线程运行一个实体测试方法,你可以为该线程加上@UIThreadTest注解。注意这将会在UI线程运行所有声明的方法。不与UI交互的方法是不允许的,例如你不能调用Instrumentation.waitForIdleSync()。

为了在UI线程中运行一个测试方法的子集,要创建一个Runnable类型的匿名类,将语句放到run()方法中,并且实例化该类的一个新实例,并把它作为一个参数传到appActicity.runOnUiThread()方法里,appActivity是你测试的应用程序的实例。

例如,下面的代码实例化一个activity来测试,为Spinner请求焦点(一个UI动作),然后给他发送一个键。注意waitForIdleSync和sendKeys是不允许在UI线程中被调用运行的。

private MyActivity mActivity; // MyActivity is the class name of the app under

test private Spinner mSpinner; ... protected void setUp() throws Exception {

super.setUp();mInstrumentation = getInstrumentation();mActivity = getActivity(); // get a references to the app under

test

mSpinner = (Spinner) mActivity.findViewById(com.android.demo.myactivity.R.id.Spinner01); ... public void aTest() {

mActivity.runOnUiThread(new Runnable() { public void run() {mSpinner.requestFocus(); }

});mInstrumentation.waitForIdleSync();

this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);

关闭触控模式

用你从测试发送的键入事件去控制模拟器或设备,你必须关闭触控模式。如果你不这样做,键入事件将被忽略。

要关闭触控模式,要在调用getActivity()启动activity前先调用ActivityInstrumentationTestCase2.setActivityTouchMode(false)。而且你必须在测试方法里的非UI线程调用此方法。所以,你不能在一个被@UIThread注解了的测试方法里调用触控模式方法。但是你可以在setUp()方法里调用来做同样的事情。

解锁模拟器和设备

你可能发现如果模拟器或设备在锁键状态下home屏幕不可见时,UI测试是不工作的。这是因为测试的应用程序不能够接收有sendKeys()发送过来的键入事件。避免这种情况最好的方法就是先启动模拟器或设备,然后禁用掉所键。

你可以显式地禁用锁键。要这样做你需要在AndroidManifest.xml配置文件里增加权限,然后在你测试的应用程序里禁用锁键。但是要注意,你一定要在发布应用程序前去掉它。

要增加权限,在元素下增加一个子元素

android:name="android.permission.DISABLE_KEYGUARD"/>,然后增加以下代码到你想要测试的activity的onCreate()方法中就能禁用掉锁键了:

mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);mLock = mKeyGuardManager.newKeyguardLock("activity_classname");mLock.disableKeyguard();

activity_classname是activity的类名

UI测试疑难解答

该部分列举了在UI测试中通常可能遇到的一些测试失败以及引起它的原因:

WrongThreadException

问题:

对于一个失败的测试,失败跟踪包含了以下错误信息:android.view.ViewRoot$CalledFromWrongThreadException: Only

the original thread that created a view hierarchy can touch its

views.

可能原因:

如果你试图从UI线程外发送UI事件到UI线程,通常会遇到这个错误。如果在没有使用@UIThread注解或者ruOnUiThread()方法的情况下,你从测试程序发送UI事件通常就会发生这个错误。该测试方法试图在UI线程外与UI交互。

解决方案建议:

在UI线程中运行交互。使用一个提供instrumentation的测试用例。参看前面的“在UI线程中测试”部分。

java.lang.RuntimeException

问题:对一个失败的测试,失败跟踪里包含以下错误信息:java.lang.RuntimeException: This method can not be

called from the main application thread

可能原因:

如果你的测试方法被@UIThreadTest注解了,但是接着又试图在UI线程外执行一些事情或者试图调用runOnUiThread()方法就会产生这种错误。

解决方案建议:

去掉@UiThreadTest注解,去掉runOnUiThread()方法调用,或者重构你的测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值