Android offers a powerful set of testing tools that extend the industry-standard JUnit testing framework for Android environments. Although you can use JUnit to test Android projects, Android tools allow you to perform more complex tests on various aspects of your application, including the unit level and the framework level.
The main features of the Android test environment are:
- Access to Android system objects.
- The instrumentation framework can control and test applications.
- An analog version of the common objects of the Android system.
- A tool that runs a single test or test suite with or without instrumentation.
- Support for managing test and test projects with the ADT plug-in and command line of Eclipse.
This article is a brief introduction to the Android test environment and test methods, and assumes that you already have some experience with Android application programming and JUnit testing.
Profile
At the heart of the Android test environment is a instrumentation framework under which your test application can precisely control the application. With instrumentation, you can create mock system objects, such as context, before the main program starts, control multiple lifecycles of the application, send UI events to the application, and check program state during execution. The instrumentation framework implements these functions by running the main program and the test program in the same process.
Specify the application to test by adding the <instrumentation> element to the manifest file in the test project. The attribute of this element indicates the name of the application package to be tested and tells Android how to run the test program. More details are described in the Inustrumentation Testrunner chapter.
The following picture outlines the test environment for Android:
In Android, the test program is also the Android program, so it and the test program are written in a lot of the same place. The SDK tool can help you create both the main program project and its test project. You can run the Android test through Eclipse's ADT plugin or command line. The Eclipse ADT provides a number of tools to create test cases, run, and view the results.
Testing API
Android provides a test API based on the JUnit test framework to write test cases and test programs. In addition, Android provides a powerful instrumentation framework that allows test cases to access the state of the program and run-time objects.
The following sections describe the main test APIs available in Android.
JUnit TestCase Class
Inherited from JUnit's testcase, cannot use the instrumentation framework. However, these classes contain methods that access system objects, such as the context. Using context, you can browse resources, files, databases, and so on. The base class is androidtestcase, and it is generally common for its subclasses to be associated with specific components.
Sub-categories are:
L applicationtestcase--Test the entire application class. It allows you to inject a simulated context into the application, initialize the test parameters before the application starts, and examine the application before the application finishes destroying.
L providertestcase2--Test the class of a single contentprovider. Because it requires the use of mockcontentresolver and injects a isolatedcontext, the provider test is isolated from the OS.
L servicetestcase--A class that tests a single service. You can inject a simulated context or simulated application (or both), or let Android provide you with context and mockapplication.
Instrumentation TestCase Class
Inherits from the JUnit TestCase class and can use the instrumentation framework for testing activity. Using Instrumentation,android, you can send events to your program to automate UI testing, and you can precisely control the activation of your activity and monitor the status of your activity's life cycle.
The base class is instrumentationtestcase. All its subclasses can send keystrokes or touch events to the UI. Subclasses can also inject a simulated intent.
Sub-categories are:
L ACTIVITYTESTCASE--ACTIVITY the base class of the Test class.
L singlelaunchactivitytestcase--Test the class of a single activity. It can trigger once setup () and teardown (), not every method call. If your test method is for the same activity, then use it.
L syncbaseinstrumentation--Test the class of content provider synchronization. It uses instrumentation to cancel an already existing synchronization object before initiating test synchronization.
L activityunittestcase--a single test class for a single activity. Using it, you can inject the simulated context or application, or both. It is used to unit test the activity.
Unlike other instrumentation classes, this test class cannot inject a simulated intent.
L activityinstrumentationtestcase2--A class that tests a single activity in a normal system environment. You can't inject a simulated context, but you can inject a simulated intent. In addition, you can run test methods on the UI thread (the main thread of the application), and you can send keystrokes and touch events to the application UI.
Assert class
Android also inherits the JUnit assert class, where there are two subclasses, Moreasserts and Viewasserts:
The L Moreasserts class contains more powerful assertion methods, such as Assertcontainsregex (String, String), which can be used as a match for regular expressions.
The L Viewasserts class contains useful assertion methods for Android view, such as asserthasscreencoordinates (view, view, int, int), which can be used to test the specific x, y position of the view in the viewable area. These asserts simplify the testing of geometry and alignment in the UI.
Mock Object class
Android has some classes that can easily create mock system objects such as Application,context,content Resolver and resource. Android also provides some methods for creating simulated intent in some test classes. Because these mock objects are easier to use than the actual objects, they can be used to simplify dependency injection. You can find these classes in Android.test and Android.test.mock.
They are:
L isolatedcontext--simulates a context so that applications can run in isolation. At the same time, there is a lot of code to help us complete the communication with the context. This class is useful in unit testing.
L renamingdelegatingcontext--When you modify the default file and database names, you can delegate most of the functions to an existing, regular context. Use this class to test the operation between the file and the database and the normal system context.
L mockapplication,mockcontentresolver,mockcontext,mockdialoginterface,mockpackagemanager,mockresources-- Creates a class of simulated system objects. They only expose methods that are useful for the management of objects. The default implementation of these methods simply throws an exception. You need to inherit these classes and override these methods.
Instrumentation Testrunner
Android provides a custom class for running test cases, called Instrumentationtestrunner. This class control application is in the test environment, running the test program and the main program in the same process, and outputting the test results to the appropriate place. The key to Intrumentationtestrunner's ability to control the entire test environment at run time is the use of instrumentation. Note that if your test class does not use instrumentation, you can also use this testrunner.
When you run a test program, you first run a system tool called activity Manager. Activity Manager uses the instrumentation framework to start and control Testrunner, which in turn uses intrumentation to close any instances of the main program, Then start the test program and the main program (in the same process). This ensures direct interaction between the test program and the main program.
Working in a test environment
Tests for Android programs are included in a test program, which is itself an Android application. The test program exists as a standalone Android project and has the same files and folders as the normal Android program. Test engineering by specifying the application to test in the manifest file.
Each test program contains one or more test cases for a particular type of component. Test cases define test methods for testing parts of the application. When you run the test program, Android loads the main program in the same process and then triggers the test method in each test case.
Test Engineering
In order to start testing for an Android program, you need to use the Android tool to create a test project. The tool creates the project folder, files, and subfolders that you want. The tool also creates a manifest file that specifies the application being tested.
Test Cases
A test program contains one or more test cases, which are inherited from the Android TestCase class. Choosing a test case class depends on the type of Android component you want to test and what kind of test you want to do. A test program can test different components, but each test case class is designed to test only a single type of component.
Some Android components have multiple test case classes associated with them. In this case, between the classes you can choose, you need to determine the type of test you want to make. For example, for activity, you have two choices, ActivityInstrumentationTestCase2 and activityunittestcase.
ActivityInstrumentationTestCase2 is designed to perform some functional testing, so it tests activity in a normal system environment. You can inject the simulated intent, but not the context of the simulation. In general, you cannot simulate dependencies between activity.
In contrast, Activityunittestcase is designed for unit testing, so it tests activity in an isolated system environment. In other words, when you use this test class, activity cannot interact with other activity.
As a rule of thumb, use ACTIVITYINSTRUMENTATIONTESTCASE2 if you want to test the activity's interaction with Android. If you want to do a regression test on an activity, use activityunittestcase.
Test method
Each test case class provides a way to establish a test environment and control the application. For example, all test case classes provide JUnit's setup () method to build a test environment. In addition, you can add methods to define individual tests. Each method you add runs once when you run the test program. If you rewrite the setup () method, it will run before each method runs. Similarly, the TearDown () method runs after each method.
The test case class provides a number of methods for component start and stop control. For this reason, before running the test, you need to explicitly tell Android to start a component. For example, you can use Getactivity () to start an activity. During the entire test case, you can only call this method one time, or one test method at a time. You can even call its finishing () in a single test method to destroy the activity, and then call Getactivity () to restart one.
Run Tests and view results
After compiling the test project, you can use the System Tools activity Manager to run the test program. You provide the activity manager with the Testrunner name (typically Instrumentationtestrunner, specified in the program); The name includes the package name of the program being tested and the name of the Testrunner. The Activity Manager loads and starts your test program, kills any instances of the main program, and then loads the main program in the same process of the test program, then passes the first test case of the test program. At this point, Testrunner will take over these test cases and run each of the test methods inside until all of the methods are run over.
If you use eclipse, the results will be displayed in JUnit's panel. If you use the command line, the output will be on the stdout.
Test what?
In addition to some functional tests, here are some things you should consider testing:
Activity life Cycle Events: You should test the correctness of activity processing lifecycle events. For example, an activity should save its state in the event of pause or destroy. Remember that a change in the orientation of the screen will also cause the current activity to be destroyed, so you need to test this accidental situation to ensure that the application state is not lost.
L Database operations: You should ensure that database operations correctly handle changes in application state. Use the Mock object in Android.test.mock.
L Screen size and resolution: Before you publish the program, make sure that you pass the test on all the screen sizes and resolutions that you want to run. You can use the AVD to test or test with a real target device.
Attach: UI Test&NBSP;
The following sections provide hints for testing the application UI, especially to help you thread handle actions, touch and key events, and lock screens in the UI line. &NBSP;
UI thread test &NBSP;
The activity runs in the program's UI thread. Once the UI has been initialized, for example, after the activity's OnCreate () method, all interaction with the UI must be run in the UI thread. When you run the program normally, it has permissions to access the thread, and nothing special happens. &NBSP;
This has changed when you run the test program. In a class with instrumentation, you can trigger a method to run in the UI thread. Other test case classes do not allow this. For a complete test method to run in the UI thread, you can use @uithreadtest to declare the thread. Note that this will run all the statements in the method in the UI thread. Methods that do not interact with the UI are not allowed to do so; for example, you cannot trigger Instrumentation.waitforidlesync (). &NBSP;
If you let a part of the code in the method run on the UI thread, create an anonymous runnable object, put the code in the Run () method, Then pass this object to Appactivity.runonuithread (), where Appactivity is the app object you want to test. &NBSP;
For example, the following code instantiates an activity to test, requests focus for spinner, and sends a key to it. Note: Waitforidlesync and SendKeys are not allowed to run 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 Sp Inner */Mspinner = (Spinner) Mactivity.findviewbyid (COM.ANDROID.DEMO.MYACTIVITY.R.ID.SPINNER01); ... public void atest () {/* * Request focus for the Spinner, so the-the-test can send key events to it * This request must is run on the UI thread. To does this, use the Runonuithread method * and pass it a Runnable that contains a call to Requestfocus on the Spinn Er. */Mactivity.runonuithread (new Runnable () {public void run () {mspinner.requestfocus (); } }); Minstrumentation.waitforidlesync (); This.senDkeys (Keyevent.keycode_dpad_center);
Turn off touchscreen mode
In order to control the key events that are sent to the emulator or device from the test program, you must turn off touchscreen mode. If you do not do this, the key event will be ignored.
When you turn off touch mode, you need to call Activityinstrumentationtestcase2.setactivitytouchmode (false) before calling Getactivity () to start the activity. You must run this call in a non-UI thread. For this reason, you cannot invoke a test method that declares to have @uithread. Can be called in Setup ().
Unlocking the simulator or device
You may have found that the UI test does not work properly if the keyboard protection mode of the emulator or device makes the home screen unavailable. This is because the application cannot receive SendKeys () events. The best way to avoid this situation is to turn off the keyboard protection mode when you start the emulator or device.
You can also explicitly turn off keyboard protection. This requires adding a permission to the manifest file and then turning off keyboard protection in the program. Note that you must remove this before you publish the program, or disable this feature in the published program.
Add <uses-permission android:name= "Androd.permission.DISABLE_KEYGUARD"/> under the <manifest> element. To turn off keyboard protection, add the following code to the OnCreate () method of the activity you are testing:
Mkeyguardmanager = (Keyguardmanager) getsystemservice (Keyguard_service);
MLock = Mkeyguardmanager.newkeyguardlock ("Activity_classname");
Mlock.disablekeyguard ();
Here, Activity_classname is the class name of the activity.
Android Testing and Instrumentation