| page.title=Service 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="#DesignAndTest">Service Design and Testing</a> | |
| </li> | |
| <li> | |
| <a href="#ServiceTestCase">ServiceTestCase</a> | |
| </li> | |
| <li> | |
| <a href="#MockObjects">Mock object classes</a> | |
| </li> | |
| <li> | |
| <a href="#TestAreas">What to Test</a> | |
| </li> | |
| </ol> | |
| <h2>Key Classes</h2> | |
| <ol> | |
| <li>{@link android.test.InstrumentationTestRunner}</li> | |
| <li>{@link android.test.ServiceTestCase}</li> | |
| <li>{@link android.test.mock.MockApplication}</li> | |
| <li>{@link android.test.RenamingDelegatingContext}</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> | |
| Android provides a testing framework for Service objects that can run them in | |
| isolation and provides mock objects. The test case class for Service objects is | |
| {@link android.test.ServiceTestCase}. Since the Service class assumes that it is separate | |
| from its clients, you can test a Service object without using instrumentation. | |
| </p> | |
| <p> | |
| This document describes techniques for testing Service objects. If you aren't familiar with the | |
| Service class, please read the <a href="{@docRoot}guide/components/services.html"> | |
| Services</a> document. If you aren't familiar with Android testing, please read | |
| <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>, | |
| the introduction to the Android testing and instrumentation framework. | |
| </p> | |
| <h2 id="DesignAndTest">Service Design and Testing</h2> | |
| <p> | |
| When you design a Service, you should consider how your tests can examine the various states | |
| of the Service lifecycle. If the lifecycle methods that start up your Service, such as | |
| {@link android.app.Service#onCreate() onCreate()} or | |
| {@link android.app.Service#onStartCommand(Intent, int, int) onStartCommand()} do not normally | |
| set a global variable to indicate that they were successful, you may want to provide such a | |
| variable for testing purposes. | |
| </p> | |
| <p> | |
| Most other testing is facilitated by the methods in the {@link android.test.ServiceTestCase} | |
| test case class. For example, the {@link android.test.ServiceTestCase#getService()} method | |
| returns a handle to the Service under test, which you can test to confirm that the Service is | |
| running even at the end of your tests. | |
| </p> | |
| <h2 id="ServiceTestCase">ServiceTestCase</h2> | |
| <p> | |
| {@link android.test.ServiceTestCase} extends the JUnit {@link junit.framework.TestCase} class | |
| with with methods for testing application permissions and for controlling the application and | |
| Service under test. It also provides mock application and Context objects that isolate your | |
| test from the rest of the system. | |
| </p> | |
| <p> | |
| {@link android.test.ServiceTestCase} defers initialization of the test environment until you | |
| call {@link android.test.ServiceTestCase#startService(Intent) ServiceTestCase.startService()} or | |
| {@link android.test.ServiceTestCase#bindService(Intent) ServiceTestCase.bindService()}. This | |
| allows you to set up your test environment, particularly your mock objects, before the Service | |
| is started. | |
| </p> | |
| <p> | |
| Notice that the parameters to <code>ServiceTestCase.bindService()</code>are different from | |
| those for <code>Service.bindService()</code>. For the <code>ServiceTestCase</code> version, | |
| you only provide an Intent. Instead of returning a boolean, | |
| <code>ServiceTestCase.bindService()</code> returns an object that subclasses | |
| {@link android.os.IBinder}. | |
| </p> | |
| <p> | |
| The {@link android.test.ServiceTestCase#setUp()} method for {@link android.test.ServiceTestCase} | |
| is called before each test. It sets up the test fixture by making a copy of the current system | |
| Context before any test methods touch it. You can retrieve this Context by calling | |
| {@link android.test.ServiceTestCase#getSystemContext()}. If you override this method, you must | |
| call <code>super.setUp()</code> as the first statement in the override. | |
| </p> | |
| <p> | |
| The methods {@link android.test.ServiceTestCase#setApplication(Application) setApplication()} | |
| and {@link android.test.AndroidTestCase#setContext(Context)} setContext()} allow you to set | |
| a mock Context or mock Application (or both) for the Service, before you start it. These mock | |
| objects are described in <a href="#MockObjects">Mock object classes</a>. | |
| </p> | |
| <p> | |
| By default, {@link android.test.ServiceTestCase} runs the test method | |
| {@link android.test.AndroidTestCase#testAndroidTestCaseSetupProperly()}, which asserts that | |
| the base test case class successfully set up a Context before running. | |
| </p> | |
| <h2 id="MockObjects">Mock object classes</h2> | |
| <p> | |
| <code>ServiceTestCase</code> assumes that you will use a mock Context or mock Application | |
| (or both) for the test environment. These objects isolate the test environment from the | |
| rest of the system. If you don't provide your own instances of these objects before you | |
| start the Service, then {@link android.test.ServiceTestCase} will create its own internal | |
| instances and inject them into the Service. You can override this behavior by creating and | |
| injecting your own instances before starting the Service | |
| </p> | |
| <p> | |
| To inject a mock Application object into the Service under test, first create a subclass of | |
| {@link android.test.mock.MockApplication}. <code>MockApplication</code> is a subclass of | |
| {@link android.app.Application} in which all the methods throw an Exception, so to use it | |
| effectively you subclass it and override the methods you need. You then inject it into the | |
| Service with the | |
| {@link android.test.ServiceTestCase#setApplication(Application) setApplication()} method. | |
| This mock object allows you to control the application values that the Service sees, and | |
| isolates it from the real system. In addition, any hidden dependencies your Service has on | |
| its application reveal themselves as exceptions when you run the test. | |
| </p> | |
| <p> | |
| You inject a mock Context into the Service under test with the | |
| {@link android.test.AndroidTestCase#setContext(Context) setContext()} method. The mock | |
| Context classes you can use are described in more detail in | |
| <a href="{@docRoot}tools/testing/testing_android.html#MockObjectClasses"> | |
| Testing Fundamentals</a>. | |
| </p> | |
| <h2 id="TestAreas">What to Test</h2> | |
| <p> | |
| The topic <a href="{@docRoot}tools/testing/what_to_test.html">What To Test</a> | |
| lists general considerations for testing Android components. | |
| Here are some specific guidelines for testing a Service: | |
| </p> | |
| <ul> | |
| <li> | |
| Ensure that the {@link android.app.Service#onCreate()} is called in response to | |
| {@link android.content.Context#startService(Intent) Context.startService()} or | |
| {@link android.content.Context#bindService(Intent,ServiceConnection,int) Context.bindService()}. | |
| Similarly, you should ensure that {@link android.app.Service#onDestroy()} is called in | |
| response to {@link android.content.Context#stopService(Intent) Context.stopService()}, | |
| {@link android.content.Context#unbindService(ServiceConnection) Context.unbindService()}, | |
| {@link android.app.Service#stopSelf()}, or | |
| {@link android.app.Service#stopSelfResult(int) stopSelfResult()}. | |
| </li> | |
| <li> | |
| Test that your Service correctly handles multiple calls from | |
| <code>Context.startService()</code>. Only the first call triggers | |
| <code>Service.onCreate()</code>, but all calls trigger a call to | |
| <code>Service.onStartCommand()</code>. | |
| <p> | |
| In addition, remember that <code>startService()</code> calls don't | |
| nest, so a single call to <code>Context.stopService()</code> or | |
| <code>Service.stopSelf()</code> (but not <code>stopSelf(int)</code>) | |
| will stop the Service. You should test that your Service stops at the correct point. | |
| </p> | |
| </li> | |
| <li> | |
| Test any business logic that your Service implements. Business logic includes checking for | |
| invalid values, financial and arithmetic calculations, and so forth. | |
| </li> | |
| </ul> |