179 lines
8.6 KiB
Plaintext
179 lines
8.6 KiB
Plaintext
page.title=Service Testing
|
|
@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}resources/tutorials/testing/helloandroid_test.html">
|
|
Hello, Testing</a>
|
|
</li>
|
|
<li>
|
|
<a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
|
|
</li>
|
|
</ol>
|
|
<h2>See Also</h2>
|
|
<ol>
|
|
<li>
|
|
<a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
|
|
Testing in Eclipse, with ADT</a>
|
|
</li>
|
|
<li>
|
|
<a href="{@docRoot}guide/developing/testing/testing_otheride.html">
|
|
Testing in 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 <a href="{@docRoot}guide/topics/fundamentals.html">
|
|
Application Fundamentals</a>. If you aren't familiar with Android testing, please read
|
|
<a href="{@docRoot}guide/topics/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}guide/topics/testing/testing_android.html#MockObjectClasses">
|
|
Testing Fundamentals</a>.
|
|
</p>
|
|
<h2 id="TestAreas">What to Test</h2>
|
|
<p>
|
|
The topic <a href="{@docRoot}guide/topics/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>
|