Address: https://developer.android.com/tools/testing/activity_testing.html
Activity testing relies heavily on the android instrumentation framework. Unlike other components, activity has a complicated lifecycle Based on callback methods. These methods cannot be called directly, except for instrumentation. At the same time, the only way in the program to send events to the UI is instrumentation.
This document describes how to use instrumentation and other test components to test an activity. This document assumes that you have read testing fundamentals, which provides a basic introduction to Android testing and instrumentation.
Activity Test API
The base class of the activity test API isInstrumentationTestCase
It provides instrumentation for your test case subclass.
For activity testing, this base class provides the following functions:
- Lifecycle control: with instrumentation, you can use the methods provided by the test case class to start, pause, and destroy the tested activity.
- Injection dependency: instrumentation allows you to create simulated system components such as context and application, and use them to start the tested activity. This helps you control the test environment and isolate it from the actual system. You can also create a custom intent and use it to start the activity.
- Ui interaction: You can use instrumentation to send a shortcut or touch time directly to the UI of the tested activity.
The activity test class is inheritedTestCase
AndAssert
Class also supports the JUnit framework.
The two subclasses used for testing are:ActivityInstrumentationTestCase2
AndActivityUnitTestCase
To test the startup of an activity in non-standard mode, you can useSingleLaunchActivityTestCase
.
Activityinstrumentationtestcase2
ActivityInstrumentationTestCase2
The test case class uses a normal system environment to test the function of one or more activities in the application. It uses the standard system context to run normally the activity in the tested application. It allows you to send a simulated intent to the tested activity, in this way, you can use it to test the activity that can process multiple types of intent, the activity that expects to receive specific types of data in intent, or the activity of both types. Note: It does not support simulated context and application, so you cannot isolate testing from normal systems.
Activityunittestcase
ActivityUnitTestCase
Test a separate activity in the case of isolation. Before starting an activity, you must inject a simulated context or application, or both. You can use it to run the activity test in isolation and perform a unit test that does not interact with Android. You cannot send a simulated intent to the tested activity, but you can callActivity.startActivity(Intent)
View the received parameters.
Singlelaunchactivitytestcase
SingleLaunchActivityTestCase
Class is a class used to test a single activity in an environment that will not change between testing and testing. It only callssetUp()
AndtearDown()
Instead of calling each test method once, it does not allow injection of any simulated object.
This test case class is useful when testing an activity to start in non-standard mode. It ensures that the test environment is not reset between the test and the test, you can test whether the activity can correctly process multiple calls.
Testing of simulated objects and activities
This section describes how to useandroid.test.mock
Content of the simulated object in the package for activity testing.
Simulated ObjectMockApplication
Only when you useActivityUnitTestCase
The test case class can only be used for activity testing. By defaultActivityUnitTestCase
Create a hiddenMockApplication
Object as the test application, you can also usesetApplication()
Inject your own objects.
Activity Test assertions
ViewAsserts
Define assertion for view. You can use it to check the view's aligning and position, or view the viewgroup status.
Test What
- Input response: test whether the activity can respond accurately After inputting data in edittext. Send the key-hitting event to the activity, and then use
findViewById(int)
To check the view status. You can enable the "OK" button when sending a valid string of key events, and the "OK" button is unavailable when inputting an invalid string of key events. You can also test whether the activity displays an error message in the view when it receives invalid characters.
- Lifecycle events: Check that each activity in your application correctly processes lifecycle events. Generally, lifecycle events are the actions that can trigger callback methods such as oncreate () or onclick (). They are from the system or user. For example, an activity should save its existing status when it receives a pause or destory event. Remember that changes in the screen direction will lead to the destory of the current activity, so you should test that the rotation of the device will not lead to the loss of the application status.
- Intent: test that each activity can correctly process the intent listed in the intent filter in the manifest file. You can use
ActivityInstrumentationTestCase2
Send a simulated intent to the activity.
- Runtime parameter change: test whether each activity can correctly handle possible configuration changes during application running. These include changes to the screen direction, changes to the current language, and how to handle these changes are described in handling runtime changes.
- Screen Size and resolution: Before you release an application, make sure that you test the screen size and size you expect to run. You can test on AVD with multiple screen sizes and resolutions, or you can test on the target machine directly. For more information, see supporting multiple screens.
Next step
To learn how to create and run a test in eclipse, see testing from eclipse with ADT. If you are not using eclipse, see testing from other ides.
If you need a hands-on test tutorial, see activity testing tutorial.
Appendix: Ui test considerations
The following content is worth attention during the ui test of the andorid application. It mainly helps you handle the events executed in the UI thread during the test, touch and press key events, and unlock the home screen.
Test in Ui thread
All activities in the application are executed in the UI thread. After the UI is instantiated, all interactions with the UI must be executed in the UI thread. When the application is started normally, you are operating the UI thread, and there is nothing special.
When you perform tests on an application, you can use the instrumentation-based class to call the UI operation method of the tested application. Other test classes are not allowed. To execute a complete test method in the UI thread, you can add annotations to the thread.@UIThreadTest
Note that all the statements of this method will be executed in the UI thread. methods that do not interact with the UI are not allowed. For example, you cannot callInstrumentation.waitForIdleSync()
.
To execute part of the test method in the UI thread, you can create a runnable Anonymous class, put the statements you need into the run () method, instantiate the class, and pass it as a parameter.appActivity.runOnUiThread()
Method, whereappActivity
Is an instance of the application you are testing.
For example, the following code instantiates a test activity, gets the focus for a spinner, and then sends a key-hitting event to it. Note:waitForIdleSync
AndsendKeys
It cannot be called in the UI thread.
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);
Disable touch mode
To use the Event Control Simulator or device you sent in the test, you must disable the touch mode. Otherwise, the key-hitting event will be ignored.
To disable touch modegetActivity()
Called before activity startupActivityInstrumentationTestCase2.setActivityTouchMode(false)
You must call this method in a non-UI thread test method.@UIThread
To disable the touch mode, you should call it in setup.
Unlock simulators or devices
The UI test does not work when the screen lock settings on the home screen enter the locked state.sendKeys()
The best solution for sending events is to enable your simulator or device and disable the home screen lock.
You can explicitly disable screen lock. You need to add a permission to the manifest file and disable the lock in the tested application. Note that you can either delete the code when releasing the application, you can use code to disable this function in published applications.
Add in the manifest File<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
As a sub-element of the <manifest> label, add the following code to oncreate () of the activity you want to test to disable lock screen:
mKeyGuardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); mLock = mKeyGuardManager.newKeyguardLock("activity_classname"); mLock.disableKeyguard();
Whereactivity_classname
Is the activity class name.
Ui test FAQ
The following lists the failures that often occur in the UI test and their causes:
WrongThreadException
:
Problem:
The failure tracking information contains the following error information:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Possible causes:
This error occurs when you try to send a UI event to the UI thread from a thread other than the UI thread. Usually occurs when a UI event is sent from the test package, but it is useless.@UIThread
Annotation orrunOnUiThread()
Method.
Suggestion:
Execute interaction in the UI thread and use a test class that provides instrumentation. See the previous testing on the UI thread.
java.lang.RuntimeException
:
Problem:
The failure tracking information contains the following error information:
java.lang.RuntimeException: This method can not be called from the main application thread
Possible causes:
This error is usually caused by your test method@UiThreadTest
Annotation, but tries to do things outside the UI thread or callrunOnUiThread()
.
Suggestion:
Delete@UiThreadTest
Annotation, deleterunOnUiThread()
Method, or refactor your test.