|  | page.title=Activity Testing | 
|  | parent.title=Testing | 
|  | parent.link=index.html | 
|  | @jd:body | 
|  |  | 
|  | <div id="qv-wrapper"> | 
|  | <div id="qv"> | 
|  | <h2>In this document</h2> | 
|  | <ol> | 
|  | <li> | 
|  | <a href="#ActivityTestAPI">The Activity Testing API</a> | 
|  | <ol> | 
|  | <li> | 
|  | <a href="#ActivityInstrumentationTestCase2">ActivityInstrumentationTestCase2</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#ActivityUnitTestCase">ActivityUnitTestCase</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#SingleLaunchActivityTestCase">SingleLaunchActivityTestCase</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#MockObjectNotes">Mock objects and activity testing</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#AssertionNotes">Assertions for activity testing</a> | 
|  | </li> | 
|  | </ol> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#WhatToTest">What to Test</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#NextSteps">Next Steps</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#UITesting">Appendix: UI Testing Notes</a> | 
|  | <ol> | 
|  | <li> | 
|  | <a href="#RunOnUIThread">Testing on the UI thread</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#NotouchMode">Turning off touch mode</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#UnlockDevice">Unlocking the Emulator or Device</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="#UITestTroubleshooting">Troubleshooting UI tests</a> | 
|  | </li> | 
|  | </ol> | 
|  | </li> | 
|  | </ol> | 
|  | <h2>Key Classes</h2> | 
|  | <ol> | 
|  | <li>{@link android.test.InstrumentationTestRunner}</li> | 
|  | <li>{@link android.test.ActivityInstrumentationTestCase2}</li> | 
|  | <li>{@link android.test.ActivityUnitTestCase}</li> | 
|  | </ol> | 
|  | <h2>Related Tutorials</h2> | 
|  | <ol> | 
|  | <li> | 
|  | <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a> | 
|  | </li> | 
|  | </ol> | 
|  | <h2>See Also</h2> | 
|  | <ol> | 
|  | <li> | 
|  | <a href="{@docRoot}tools/testing/testing_eclipse.html"> | 
|  | Testing from Eclipse with ADT</a> | 
|  | </li> | 
|  | <li> | 
|  | <a href="{@docRoot}tools/testing/testing_otheride.html"> | 
|  | Testing from Other IDEs</a> | 
|  | </li> | 
|  | </ol> | 
|  | </div> | 
|  | </div> | 
|  | <p> | 
|  | Activity testing is particularly dependent on the Android instrumentation framework. | 
|  | Unlike other components, activities have a complex lifecycle based on callback methods; these | 
|  | can't be invoked directly except by instrumentation. Also, the only way to send events to the | 
|  | user interface from a program is through instrumentation. | 
|  | </p> | 
|  | <p> | 
|  | This document describes how to test activities using instrumentation and other test | 
|  | facilities. The document assumes you have already read | 
|  | <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>, | 
|  | the introduction to the Android testing and instrumentation framework. | 
|  | </p> | 
|  | <h2 id="ActivityTestAPI">The Activity Testing API</h2> | 
|  | <p> | 
|  | The activity testing API base class is {@link android.test.InstrumentationTestCase}, | 
|  | which provides instrumentation to the test case subclasses you use for Activities. | 
|  | </p> | 
|  | <p> | 
|  | For activity testing, this base class provides these functions: | 
|  | </p> | 
|  | <ul> | 
|  | <li> | 
|  | Lifecycle control: With instrumentation, you can start the activity under test, pause it, | 
|  | and destroy it, using methods provided by the test case classes. | 
|  | </li> | 
|  | <li> | 
|  | Dependency injection: Instrumentation allows you to create mock system objects such as | 
|  | Contexts or Applications and use them to run the activity under test. This | 
|  | helps you control the test environment and isolate it from production systems. You can | 
|  | also set up customized Intents and start an activity with them. | 
|  | </li> | 
|  | <li> | 
|  | User interface interaction: You use instrumentation to send keystrokes or touch events | 
|  | directly to the UI of the activity under test. | 
|  | </li> | 
|  | </ul> | 
|  | <p> | 
|  | The activity testing classes also provide the JUnit framework by extending | 
|  | {@link junit.framework.TestCase} and {@link junit.framework.Assert}. | 
|  | </p> | 
|  | <p> | 
|  | The two main testing subclasses are {@link android.test.ActivityInstrumentationTestCase2} and | 
|  | {@link android.test.ActivityUnitTestCase}. To test an Activity that is launched in a mode | 
|  | other than <code>standard</code>, you use {@link android.test.SingleLaunchActivityTestCase}. | 
|  | </p> | 
|  | <h3 id="ActivityInstrumentationTestCase2">ActivityInstrumentationTestCase2</h3> | 
|  | <p> | 
|  | The {@link android.test.ActivityInstrumentationTestCase2} test case class is designed to do | 
|  | functional testing of one or more Activities in an application, using a normal system | 
|  | infrastructure. It runs the Activities in a normal instance of the application under test, | 
|  | using a standard system Context. It allows you to send mock Intents to the activity under | 
|  | test, so you can use it to test an activity that responds to multiple types of intents, or | 
|  | an activity that expects a certain type of data in the intent, or both. Notice, though, that it | 
|  | does not allow mock Contexts or Applications, so you can not isolate the test from the rest of | 
|  | a production system. | 
|  | </p> | 
|  | <h3 id="ActivityUnitTestCase">ActivityUnitTestCase</h3> | 
|  | <p> | 
|  | The {@link android.test.ActivityUnitTestCase} test case class tests a single activity in | 
|  | isolation. Before you start the activity, you can inject a mock Context or Application, or both. | 
|  | You use it to run activity tests in isolation, and to do unit testing of methods | 
|  | that do not interact with Android. You can not send mock Intents to the activity under test, | 
|  | although you can call | 
|  | {@link android.app.Activity#startActivity(Intent) Activity.startActivity(Intent)} and then | 
|  | look at arguments that were received. | 
|  | </p> | 
|  | <h3 id="SingleLaunchActivityTestCase">SingleLaunchActivityTestCase</h3> | 
|  | <p> | 
|  | The {@link android.test.SingleLaunchActivityTestCase} class is a convenience class for | 
|  | testing a single activity in an environment that doesn't change from test to test. | 
|  | It invokes {@link junit.framework.TestCase#setUp() setUp()} and | 
|  | {@link junit.framework.TestCase#tearDown() tearDown()} only once, instead of once per | 
|  | method call. It does not allow you to inject any mock objects. | 
|  | </p> | 
|  | <p> | 
|  | This test case is useful for testing an activity that runs in a mode other than | 
|  | <code>standard</code>. It ensures that the test fixture is not reset between tests. You | 
|  | can then test that the activity handles multiple calls correctly. | 
|  | </p> | 
|  | <h3 id="MockObjectNotes">Mock objects and activity testing</h3> | 
|  | <p> | 
|  | This section contains notes about the use of the mock objects defined in | 
|  | {@link android.test.mock} with activity tests. | 
|  | </p> | 
|  | <p> | 
|  | The mock object {@link android.test.mock.MockApplication} is only available for activity | 
|  | testing if you use the {@link android.test.ActivityUnitTestCase} test case class. | 
|  | By default, <code>ActivityUnitTestCase</code>, creates a hidden <code>MockApplication</code> | 
|  | object that is used as the application under test. You can inject your own object using | 
|  | {@link android.test.ActivityUnitTestCase#setApplication(Application) setApplication()}. | 
|  | </p> | 
|  | <h3 id="AssertionNotes">Assertions for activity testing</h3> | 
|  | <p> | 
|  | {@link android.test.ViewAsserts} defines assertions for Views. You use it to verify the | 
|  | alignment and position of View objects, and to look at the state of ViewGroup objects. | 
|  | </p> | 
|  | <h2 id="WhatToTest">What To Test</h2> | 
|  | <ul> | 
|  | <li> | 
|  | Input validation: Test that an activity responds correctly to input values in an | 
|  | EditText View. Set up a keystroke sequence, send it to the activity, and then | 
|  | use {@link android.view.View#findViewById(int)} to examine the state of the View. You can | 
|  | verify that a valid keystroke sequence enables an OK button, while an invalid one leaves the | 
|  | button disabled. You can also verify that the Activity responds to invalid input by | 
|  | setting error messages in the View. | 
|  | </li> | 
|  | <li> | 
|  | Lifecycle events: Test that each of your application's activities handles lifecycle events | 
|  | correctly. In general, lifecycle events are actions, either from the system or from the | 
|  | user, that trigger a callback method such as <code>onCreate()</code> or | 
|  | <code>onClick()</code>. For example, an activity should respond to pause or destroy events | 
|  | by saving its state. Remember that even a change in screen orientation causes the current | 
|  | activity to be destroyed, so you should test that accidental device movements don't | 
|  | accidentally lose the application state. | 
|  | </li> | 
|  | <li> | 
|  | Intents: Test that each activity correctly handles the intents listed in the intent | 
|  | filter specified in its manifest. You can use | 
|  | {@link android.test.ActivityInstrumentationTestCase2} to send mock Intents to the | 
|  | activity under test. | 
|  | </li> | 
|  | <li> | 
|  | Runtime configuration changes: Test that each activity responds correctly to the | 
|  | possible changes in the device's configuration while your application is running. These | 
|  | include a change to the device's orientation, a change to the current language, and so | 
|  | forth. Handling these changes is described in detail in the topic | 
|  | <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime | 
|  | Changes</a>. | 
|  | </li> | 
|  | <li> | 
|  | Screen sizes and resolutions: Before you publish your application, make sure to test it on | 
|  | all of the screen sizes and densities on which you want it to run. You can test the | 
|  | application on multiple sizes and densities using AVDs, or you can test your application | 
|  | directly on the devices that you are targeting. For more information, see the topic | 
|  | <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>. | 
|  | </li> | 
|  | </ul> | 
|  | <h2 id="NextSteps">Next Steps</h2> | 
|  | <p> | 
|  | To learn how to set up and run tests in Eclipse, please refer to | 
|  | <a href="{@docRoot}tools/testing/testing_eclipse.html">Testing from Eclipse with ADT</a>. | 
|  | If you're not working in Eclipse, refer to | 
|  | <a href="{@docRoot}tools/testing/testing_otheride.html">Testing from Other IDEs</a>. | 
|  | </p> | 
|  | <p> | 
|  | If you want a step-by-step introduction to testing activities, try the | 
|  | <a href="{@docRoot}tools/testing/activity_test.html">Activity Testing Tutorial</a>, which | 
|  | guides you through a testing scenario that you develop against an activity-oriented application. | 
|  | </p> | 
|  | <h2 id="UITesting">Appendix: UI Testing Notes</h2> | 
|  | <p> | 
|  | The following sections have tips for testing the UI of your Android application, specifically | 
|  | to help you handle actions that run in the UI thread, touch screen and keyboard events, and home | 
|  | screen unlock during testing. | 
|  | </p> | 
|  | <h3 id="RunOnUIThread">Testing on the UI thread</h3> | 
|  | <p> | 
|  | An application's activities run on the application's <strong>UI thread</strong>. Once the | 
|  | UI is instantiated, for example in the activity's <code>onCreate()</code> method, then all | 
|  | interactions with the UI must run in the UI thread. When you run the application normally, it | 
|  | has access to the thread and does not have to do anything special. | 
|  | </p> | 
|  | <p> | 
|  | This changes when you run tests against the application. With instrumentation-based classes, | 
|  | you can invoke methods against the UI of the application under test. The other test classes | 
|  | don't allow this. To run an entire test method on the UI thread, you can annotate the thread | 
|  | with <code>@UiThreadTest</code>. Notice that this will run <em>all</em> of the method statements | 
|  | on the UI thread.  Methods that do not interact with the UI are not allowed; for example, you | 
|  | can't invoke <code>Instrumentation.waitForIdleSync()</code>. | 
|  | </p> | 
|  | <p> | 
|  | To run a subset of a test method on the UI thread, create an anonymous class of type | 
|  | <code>Runnable</code>, put the statements you want in the <code>run()</code> method, and | 
|  | instantiate a new instance of the class as a parameter to the method | 
|  | <code><em>appActivity</em>.runOnUiThread()</code>, where <code><em>appActivity</em></code> is | 
|  | the instance of the application you are testing. | 
|  | </p> | 
|  | <p> | 
|  | For example, this code instantiates an activity to test, requests focus (a UI action) for the | 
|  | Spinner displayed by the activity, and then sends a key to it. Notice that the calls to | 
|  | <code>waitForIdleSync</code> and <code>sendKeys</code> aren't allowed to run on the UI thread: | 
|  | </p> | 
|  | <pre> | 
|  | 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 | 
|  |  | 
|  | /* | 
|  | * Get a reference to the main widget of the app under test, a Spinner | 
|  | */ | 
|  | mSpinner = (Spinner) mActivity.findViewById(com.android.demo.myactivity.R.id.Spinner01); | 
|  |  | 
|  | ... | 
|  |  | 
|  | public void aTest() { | 
|  | /* | 
|  | * request focus for the Spinner, so that the test can send key events to it | 
|  | * This request must be run on the UI thread. To do this, use the runOnUiThread method | 
|  | * and pass it a Runnable that contains a call to requestFocus on the Spinner. | 
|  | */ | 
|  | mActivity.runOnUiThread(new Runnable() { | 
|  | public void run() { | 
|  | mSpinner.requestFocus(); | 
|  | } | 
|  | }); | 
|  |  | 
|  | mInstrumentation.waitForIdleSync(); | 
|  |  | 
|  | this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); | 
|  | </pre> | 
|  |  | 
|  | <h3 id="NotouchMode">Turning off touch mode</h3> | 
|  | <p> | 
|  | To control the emulator or a device with key events you send from your tests, you must turn off | 
|  | touch mode. If you do not do this, the key events are ignored. | 
|  | </p> | 
|  | <p> | 
|  | To turn off touch mode, you invoke | 
|  | <code>ActivityInstrumentationTestCase2.setActivityTouchMode(false)</code> | 
|  | <em>before</em> you call <code>getActivity()</code> to start the activity. You must invoke the | 
|  | method in a test method that is <em>not</em> running on the UI thread. For this reason, you | 
|  | can't invoke the touch mode method from a test method that is annotated with | 
|  | <code>@UIThread</code>. Instead, invoke the touch mode method from <code>setUp()</code>. | 
|  | </p> | 
|  | <h3 id="UnlockDevice">Unlocking the emulator or device</h3> | 
|  | <p> | 
|  | You may find that UI tests don't work if the emulator's or device's home screen is disabled with | 
|  | the keyguard pattern. This is because the application under test can't receive key events sent | 
|  | by <code>sendKeys()</code>. The best way to avoid this is to start your emulator or device | 
|  | first and then disable the keyguard for the home screen. | 
|  | </p> | 
|  | <p> | 
|  | You can also explicitly disable the keyguard. To do this, | 
|  | you need to add a permission in the manifest file (<code>AndroidManifest.xml</code>) and | 
|  | then disable the keyguard in your application under test. Note, though, that you either have to | 
|  | remove this before you publish your application, or you have to disable it with code in | 
|  | the published application. | 
|  | </p> | 
|  | <p> | 
|  | To add the permission, add the element | 
|  | <code><uses-permission android:name="android.permission.DISABLE_KEYGUARD"/></code> | 
|  | as a child of the <code><manifest></code> element. To disable the KeyGuard, add the | 
|  | following code to the <code>onCreate()</code> method of activities you intend to test: | 
|  | </p> | 
|  | <pre> | 
|  | mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); | 
|  | mLock = mKeyGuardManager.newKeyguardLock("<em>activity_classname</em>"); | 
|  | mLock.disableKeyguard(); | 
|  | </pre> | 
|  | <p>where <code><em>activity_classname</em></code> is the class name of the activity.</p> | 
|  | <h3 id="UITestTroubleshooting">Troubleshooting UI tests</h3> | 
|  | <p> | 
|  | This section lists some of the common test failures you may encounter in UI testing, and their | 
|  | causes: | 
|  | </p> | 
|  | <dl> | 
|  | <dt><code>WrongThreadException</code></dt> | 
|  | <dd> | 
|  | <p><strong>Problem:</strong></p> | 
|  | For a failed test, the Failure Trace contains the following error message: | 
|  | <code> | 
|  | android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created | 
|  | a view hierarchy can touch its views. | 
|  | </code> | 
|  | <p><strong>Probable Cause:</strong></p> | 
|  | This error is common if you tried to send UI events to the UI thread from outside the UI | 
|  | thread. This commonly happens if you send UI events from the test application, but you don't | 
|  | use the <code>@UIThread</code> annotation or the <code>runOnUiThread()</code> method. The | 
|  | test method tried to interact with the UI outside the UI thread. | 
|  | <p><strong>Suggested Resolution:</strong></p> | 
|  | Run the interaction on the UI thread. Use a test class that provides instrumentation. See | 
|  | the previous section <a href="#RunOnUIThread">Testing on the UI Thread</a> | 
|  | for more details. | 
|  | </dd> | 
|  | <dt><code>java.lang.RuntimeException</code></dt> | 
|  | <dd> | 
|  | <p><strong>Problem:</strong></p> | 
|  | For a failed test, the Failure Trace contains the following error message: | 
|  | <code> | 
|  | java.lang.RuntimeException: This method can not be called from the main application thread | 
|  | </code> | 
|  | <p><strong>Probable Cause:</strong></p> | 
|  | This error is common if your test method is annotated with <code>@UiThreadTest</code> but | 
|  | then tries to do something outside the UI thread or tries to invoke | 
|  | <code>runOnUiThread()</code>. | 
|  | <p><strong>Suggested Resolution:</strong></p> | 
|  | Remove the <code>@UiThreadTest</code> annotation, remove the <code>runOnUiThread()</code> | 
|  | call, or re-factor your tests. | 
|  | </dd> | 
|  | </dl> |