blob: 1302217f6ba09c50217eef121572e185c10d8606 [file] [log] [blame]
David Warren5f6ca4f2009-04-30 17:11:58 -07001page.title=Instrumentation Testing
2pdk.version=1.0
3@jd:body
4
5<a name="toc"/>
6<div style="padding:10px">
7<a href="#androidInstrumentationFrameworkIntro">Introduction</a><br/>
8<a href="#androidInstrumentationTestingFramework">Instrumentation Framework</a><br/><div style="padding-left:40px">
9
10<a href="#androidInstrumentationTestingClasses">Classes</a><br/>
11<a href="#androidInstrumentationFrameworkamCommand">Understanding the am Command</a><br/></div>
12<a href="#androidInstrumentationFrameworkPlatform">Platform Test Suites</a><br/><div style="padding-left:40px">
13
14<a href="#androidTestingPlatformFramework">Framework Tests</a><br/>
15<a href="#androidTestingPlatformCoreLibrary">Core Library</a><br/></div>
16<a href="#androidInstrumentationFrameworkWritingRunning">Running Tests</a><br/><div style="padding-left:40px">
17
18<a href="#androidInstrumentationTestingRunningAll">All Tests with Default TestRunner behavior</a><br/>
19<a href="#androidTestingTestSinglePakcage">Running all Tests Under Single Package</a><br/>
20<a href="#androidTestingSingleTestSuite">Running a Single Test Suite</a><br/>
21<a href="#androidInstrumentationTestingRunningSingleTestCase">A Single Test Case</a><br/>
22<a href="#androidInstrumentationTestingRunningSingleTest">A Single Test</a><br/>
23<a href="#androidTestingDebugging">Attaching a debugger to your test</a><br/></div>
24<a href="#androidInstrumentationTestingCreating">Writing Tests</a><br/><div style="padding-left:40px">
25
26<a href="#androidTestingLocationFiles">Location of Files</a><br/>
27<a href="#androidTestingContentMakefile">Contents of makefile</a><br/>
28<a href="#androidTestingContentManifest">Content of Manifest</a><br/>
29<a href="#androidInstrumentationTestingCreatingTestRunner">New Instrumentation TestRunner</a><br/>
30<a href="#androidInstrumentationTestingCreatingTestCase">New InstrumentationTestCase</a><br/>
31<a href="#androidInstrumentationFrameworkTestCase">Exploring a Test Case</a><br/>
32<a href="#androidTestingKindsofTests">Deciding Kinds of Tests to Write</a><br/></div>
33<a href="#androidInstrumentationFrameworkTroubleshooting">Troubleshooting</a><br/></div>
34
35<a name="androidInstrumentationFrameworkIntro"></a><h2>Introduction</h2>
36
37<p>This document describes how to use the Instrumentation Framework to write test cases. Instrumentation testing allows you to verify a particular feature or behavior with an automated JUnit TestCase. You can launch activities and providers within an application, send key events, and make assertions about various UI elements. </p>
38<p>You should have a working knowledge of the following:</p>
39<ul>
40 <li> Android Application Framework</li>
41 <li> Using <code>adb</code>, <code>am</code> and various logging functionality </li>
42 <li> A brief understanding of the application of interest, that is, the names of the classes which handle the intents etc. </li>
43 <li> JUnit testing.</li>
44</ul>
45<p> Each Android application runs in its own process. Instrumentation kills the application process and restarts the process with Instrumentation. Instrumentation gives a handle to the application context used to poke around the application to validate test assertions, allowing you to write test cases to test applications at a much lower level than UI screen shot tests. Note that Instrumentation cannot catch UI bugs. </p>
46
47
48<a name="androidInstrumentationTestingFramework"></a><h2>Instrumentation Framework</h2>
49
50
51
52<a name="androidInstrumentationTestingClasses"></a><h3>Classes</h3>
53
54<p> The following classes help glue together <code>Instrumentation</code> with JUnit testing. </p>
55<table>
56 <tr>
57 <th scope="col">Class</th>
58 <th scope="col">Description</th></tr>
59 <tr>
60 <td valign="top"><code>InstrumentationTestCase</code></td>
61 <td valign="top">
62 <p>This extends the standard JUnit <code>TestCase</code> and offers access to an <code>Instrumentation</code> class. Write tests inside your instrumentation class any way you see fit. For example, your test might launch activities and send key events. For this to work properly, the instrumentation needs to be injected into the test case.</p> </td>
63 </tr>
64 <tr>
65 <td valign="top"><code>InstrumentationTestRunner</code></td>
66 <td valign="top">The instrumentation test runner is an instrumentation that runs instrumentation test cases and injects itself into each test case. Instrumentation test cases need to be grouped together with an instrumentation test runner with the appropriate target package.</td>
67 </tr>
68 <tr>
69 <td valign="top"><code>InstrumentationTestSuite</code></td>
70 <td valign="top">The instrumentation test suite is a simple extension of the standard JUnit <code>TestSuite</code> that keeps a member <code>Instrumentation</code> variable on hand to inject into each <code>TestCase</code> before running them. It is used by <code>InstrumentationTestRunner</code>.</td>
71 </tr>
72</table>
73<p> Three additional base classes extend <code>InstrumentationTestCase</code> to allow you to test <code>Activity</code> and <code>Provider</code> classes:</p>
74<table>
75 <tr>
76 <th scope="col">Class</th>
77 <th scope="col">Description</th>
78 </tr>
79 <tr>
80 <td valign="top"><code>ActivityTestCase</code></td>
81 <td valign="top"><p>This class can be used to write tests for a specific activity. An activity is launched in its <code>setUp()</code> method and finished with <code>tearDown</code>. If you write a test case that extends <code>ActivityTestCase</code>, you can write tests that access the activity using <code>getActivity()</code> and assume it has been set up properly.</p></td>
82 </tr>
83 <tr>
84 <td valign="top"><code>ServiceTestCase</code></td>
85 <td valign="top">This test case provides a framework in which you can test Service classes in a controlled environment. It provides basic support for the lifecycle of a Service, and hooks by which you can inject various dependencies and control the environment in which your Service is tested.</td>
86 </tr>
87 <tr>
88 <td valign="top"><code>SingleLaunchActivityTestCase</code></td>
89 <td valign="top">This class is similar to <code>ActivityTestCase</code> except that the activity is launched once per class instead of every time the test case calls setup. </td>
90 </tr>
91 <tr>
92 <td valign="top"><code>ProviderTestCase</code></td>
93 <td valign="top">This class is similar to <code>ActivityTestCase</code> except that it will setup, tear down, and provide access to the <code>Provider</code> of your choice.</td>
94 </tr>
95</table>
96
97
98<a name="androidInstrumentationFrameworkamCommand"></a><h3>Understanding the am Command</h3>
99
100<p>The am command is a command-line interface to the ActivityManager (see <a href="http://code.google.com/android/reference/android/app/ActivityManager.html">http://code.google.com/android/reference/android/app/ActivityManager.html</a> for details). <code>am</code> is used to start and instrument activities using the adb shell command, as shown in the snippet below:</p>
101<pre class="prettify">
102&gt; adb shell am
103usage: am [start|instrument]
104 am start [-a &lt;ACTION&gt;] [-d &lt;DATA_URI&gt;] [-t &lt;MIME_TYPE&gt;]
105 [-c &lt;CATEGORY&gt; [-c &lt;CATEGORY&gt;] ...]
106 [-e &lt;EXTRA_KEY&gt; &lt;EXTRA_VALUE&gt; [-e &lt;EXTRA_KEY&gt; &lt;EXTRA_VALUE&gt; ...]
107 [-n &lt;COMPONENT&gt;] [-D] [&lt;URI&gt;]
108 am instrument [-e &lt;ARG_NAME&gt; &lt;ARG_VALUE&gt;] [-p &lt;PROF_FILE&gt;]
109 [-w] &lt;COMPONENT&gt;
110For example, to start the Contacts application you can use
111&gt; adb shell am start -n com.google.android.contacts/.ContactsActivity
112</pre>
113
114
115<a name="androidInstrumentationFrameworkPlatform"></a><h2>Platform Test Suites</h2>
116
117<p>This section provides an overview for various unit and functional test cases that can be executed through the instrumentation framework.</p>
118
119
120<a name="androidTestingPlatformFramework"></a><h3>Framework Tests</h3>
121
122<p>Framework test cases test the Android application framework or specific Android application functionality that requires an Android runtime context. These tests can be found in <code>//device/tests</code> and <code>//device/apps/AndroidTests</code>.</p>
123
124
125<a name="androidTestingPlatformCoreLibrary"></a><h3>Core Library</h3>
126
127<p>Core library test cases test the Android library functionality that does not require an Android runtime context. These tests are split into Android library (android.* package space) tests at <code>//device/java/tests</code> and Java library (java.*, javax.*, etc. packages) tests at <code>//device/dalvik/libcore/.../tests</code>.</p>
128
129
130<a name="androidInstrumentationFrameworkWritingRunning"></a><h2>Running Tests</h2>
131
132<p>Each instrumentation test case is similar to an Android application with the distinction that it starts another application. For example, have a look in the <code>tests/Contacts</code> directory. </p>
133<ul>
134 <li> There should be a Makefile and an Android Manifest file. </li>
135 <li> Tests are located in <code>tests/Contacts/src/com/google/android/contactstests</code>. </li>
136 <li> The Instrumentation Test Runner is located at <code>tests/Contacts/src/com/google/android/contactstests/functional/ContactsInstrumentationTestRunner.java</code>.</li>
137</ul>
138<p>Suppose you have a makefile with <code>Contactstests</code> as the target. </p>
139<ul>
140 <li> <code>make Contactstests</code>: Compiles the test cases. </li>
141 <li> <code>adb install Contactstests.apk</code>: Installs the apk on the device. </li>
142 <li> Use the adb shell <code>am</code> command to run them. </li>
143</ul>
144<p> To run your tests, use the <code>am instrument</code> command with your <code>InstrumentationTestRunner</code> as its argument. Results are printed as a result of the instrumentation. For example, the following snippet displays the output after running the framework tests with one test failing (note the unusual syntax caused by how instrumentations are run via <code>am</code>):</p>
145<pre class="prettify">
146$ adb shell am instrument -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner
147INSTRUMENTATION_RESULT: test results:=.......F.......
148Time: 6.837
149There was 1 failure:
1501) testSetUpConditions(com.google.android.frameworktest.tests.focus.RequestFocusTest)junit.framework.AssertionFailedError: requestFocus() should work from onCreate.
151 at com.google.android.frameworktest.tests.focus.RequestFocusTest.testSetUpConditions(RequestFocusTest.java:66)
152 at java.lang.reflect.Method.invokeNative(Native Method)
153 at android.test.InstrumentationTestSuite.runTest(InstrumentationTestSuite.java:73)
154 at android.test.InstrumentationTestSuite.runTest(InstrumentationTestSuite.java:73)
155 at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:151)
156 at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1088)
157
158FAILURES!!!
159Tests run: 14, Failures: 1, Errors: 0
160
161&lt;RETURN&gt; to continue
162
163INSTRUMENTATION_CODE: -1
164$
165</pre>
166
167
168<a name="androidInstrumentationTestingRunningAll"></a><h3>All Tests with Default TestRunner behavior</h3>
169
170<p>If no class or package is passed in to run, InstrumentationTestRunner will automatically find and run all tests under the package of the test application (as defined by the <code>android:targetPackage</code> attribute of the instrumentation defined in its manifest file).
171</p>
172<pre>
173$ adb shell am instrument -w \
174 com.android.samples.tests/android.test.InstrumentationTestRunner
175
176INSTRUMENTATION_RESULT: Test results for InstrumentationTestRunner=..........
177Time: 2.317
178
179OK (10 tests)
180
181
182INSTRUMENTATION_CODE: -1
183</pre>
184
185
186<a name="androidTestingTestSinglePakcage"></a><h3>Running all Tests Under Single Package</h3>
187
188<p>If you have many tests under one package, use the <code>-e package &lt;packagename&gt;</code> option to run all tests under that package without having to manually create a test suite.</p>
189<pre>
190$ adb shell am instrument -w \
191 -e package com.android.samples.view \
192 com.android.samples.tests/android.test.InstrumentationTestRunner
193INSTRUMENTATION_RESULT: Test results for InstrumentationTestRunner=........
194Time: 1.587
195
196OK (8 tests)
197</pre>
198
199
200<a name="androidTestingSingleTestSuite"></a><h3>Running a Single Test Suite</h3>
201
202<p>If you prefer to explicitly state which tests comprise all of your tests, you can define a test suite and run that directly. By convention, all test packages in your system should have at least one suite called <code>AllTests</code> (see <code>AllTests.java</code>). To run all of the tests using the <code>AllTests</code> suite for the api demos test app:</p>
203
204<pre>
205$ adb shell am instrument -w \
206 -e class com.android.samples.AllTests \
207 com.android.samples.tests/android.test.InstrumentationTestRunner
208
209INSTRUMENTATION_RESULT: Test results for AllTests=..........
210Time: 2.286
211
212OK (10 tests)
213
214
215INSTRUMENTATION_CODE: -1
216</pre>
217
218
219<a name="androidInstrumentationTestingRunningSingleTestCase"></a><h3>A Single Test Case</h3>
220
221<pre>
222$ adb shell am instrument -w \
223 -e class com.android.samples.view.Focus2ActivityTest \
224 com.android.samples.tests/android.test.InstrumentationTestRunner
225
226INSTRUMENTATION_RESULT: Test results for Focus2ActivityTest=....
227Time: 1.359
228
229OK (4 tests)
230
231
232INSTRUMENTATION_CODE: -1
233</pre>
234
235
236<a name="androidInstrumentationTestingRunningSingleTest"></a><h3>A Single Test</h3>
237
238<pre>
239$ adb shell am instrument -w \
240 -e class com.android.samples.view.Focus2ActivityTest#testGoingLeftFromRightButtonGoesToCenter \
241 com.android.samples.tests/android.test.InstrumentationTestRunner
242
243INSTRUMENTATION_RESULT: Test results for Focus2ActivityTest=.
244Time: 0.51
245
246OK (1 test)
247
248
249INSTRUMENTATION_CODE: -1
250</pre>
251
252
253<a name="androidTestingDebugging"></a><h3>Attaching a debugger to your test</h3>
254
255<p>In order to debug your test code, instruct the controller to stop and wait for the debugger by adding <code>-e debug true</code> to your
256command line. This causes the test runner to stop and wait for the debugger just before calling your <code>setUp()</code> method. For example,</p>
257
258<pre>
259$ adb shell am instrument -w \
260 -e debug true \
261 com.android.samples.tests/android.test.InstrumentationTestRunner
262</pre>
263
264
265<a name="androidInstrumentationTestingCreating"></a><h2>Writing Tests</h2>
266
267<p>When writing tests, refer to the ApiDemos tests as models (located at <code>//device/samples/ApiDemos</code>). This section provides an overview of the test structure with ApiDemos.</p>
268
269
270<a name="androidTestingLocationFiles"></a><h3>Location of Files</h3>
271
272<p>Test packages should use the following structure and include <code>Android.mk</code>, <code>AndroidManifest.xml</code>, <code>AllTests.java</code>, and a src directory that mirrors the src directory of the tested application.</p>
273<p>Files are located within a <code>tests</code> directory found in the root directory:</p>
274<pre>
275$ find samples/ApiDemos/tests
276samples/ApiDemos/tests
277samples/ApiDemos/tests/Android.mk
278samples/ApiDemos/tests/AndroidManifest.xml
279samples/ApiDemos/tests/src
280samples/ApiDemos/tests/src/com
281samples/ApiDemos/tests/src/com/google
282samples/ApiDemos/tests/src/com/google/android
283samples/ApiDemos/tests/src/com/google/android/samples
284samples/ApiDemos/tests/src/com/google/android/samples/AllTests.java
285samples/ApiDemos/tests/src/com/google/android/samples/ApiDemosTest.java
286samples/ApiDemos/tests/src/com/google/android/samples/os
287samples/ApiDemos/tests/src/com/google/android/samples/os/MorseCodeConverterTest.java
288samples/ApiDemos/tests/src/com/google/android/samples/view
289samples/ApiDemos/tests/src/com/google/android/samples/view/Focus2ActivityTest.java
290samples/ApiDemos/tests/src/com/google/android/samples/view/Focus2AndroidTest.java
291</pre>
292
293
294<a name="androidTestingContentMakefile"></a><h3>Contents of makefile</h3>
295
296<p>The contents of the makefile are similar to a normal application with the addition of a <code>LOCAL_INSTRUMENTATION_FOR</code> declaration.<p />
297<pre>
298# Add appropriate copyright banner here
299LOCAL_PATH:= $(call my-dir)
300include $(CLEAR_VARS)
301
302# We only want this apk build for tests.
303LOCAL_MODULE_TAGS := tests
304
305# Include all test java files.
306LOCAL_SRC_FILES := $(call all-java-files-under, src)
307
308# Notice that we don't have to include the src files of ApiDemos because, by
309# running the tests using an instrumentation targeting ApiDemos, we
310# automatically get all of its classes loaded into our environment.
311
312LOCAL_PACKAGE_NAME := ApiDemosTests
313
314LOCAL_INSTRUMENTATION_FOR := ApiDemos
315
316include $(BUILD_PACKAGE)
317</pre>
318
319
320<a name="androidTestingContentManifest"></a><h3>Content of Manifest</h3>
321
322<p>Use the following example to create an <code>AndroidManifest.xml</code> file that declares the instrumentation. Specify that the framework supplied Instrumentation TestRunner targest the package of your application, allowing the tests that are run with the instrumentation to get access to all of the classes of your application without having to build the source into the test app. The name of the test application is typically the same as your target application with <code>.tests</code> appended. </p>
323<pre>
324# Add appropriate copyright banner here
325&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
326 package="com.android.samples.tests"&gt;
327
328 &lt;uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /&gt;
329
330 &lt;!--
331 This declares that this app uses the instrumentation test runner targeting
332 the package of com.android.samples. To run the tests use the command:
333 "adb shell am instrument -w com.android.samples.tests/android.test.InstrumentationTestRunner"
334 --&gt;
335 &lt;instrumentation android:name="android.test.InstrumentationTestRunner"
336 android:targetPackage="com.android.samples"
337 android:label="Tests for Api Demos."/&gt;
338
339&lt;/manifest&gt;
340</pre>
341<p>&nbsp;</p>
342<p>The following snippet will prefix the <code>/android.test.InstrumentationTestRunner</code> when running tests from the command line:</p>
343<pre>
344$ adb shell am instrument -w \
345 com.android.samples.tests/android.test.InstrumentationTestRunner
346</pre>
347
348
349<a name="androidInstrumentationTestingCreatingTestRunner"></a><h3>New Instrumentation TestRunner</h3>
350
351<p>Create a class that derives from this class. You must override two abstract methods; one that returns the class loader of the target package, and another that defines all of the tests within the package. For example, the snippet below displays the test runner for the framework tests.</p>
352<pre class="prettify">
353public class FrameworkInstrumentationTestRunner extends InstrumentationTestRunner {
354
355 @Override
356 public TestSuite getAllTests() {
357 InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
358
359 suite.addTestSuite(FocusAfterRemovalTest.class);
360 suite.addTestSuite(RequestFocusTest.class);
361 suite.addTestSuite(RequestRectangleVisibleTest.class);
362 return suite;
363 }
364
365 @Override
366 public ClassLoader getLoader() {
367 return FrameworkInstrumentationTestRunner.class.getClassLoader();
368 }
369}
370</pre>
371<p> Next, in an appropriate <code>AndroidManifest.xml</code>, define the instrumentation for the derived class with the appropriate <code>android:targetPackage</code> set. For example, the snippet below defines the instrumentation runner for the framework tests.</p>
372<pre class="prettify">
373&lt;uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /&gt;
374
375&lt;instrumentation android:name="android.tests.FrameworkInstrumentationTestRunner"
376 android:targetPackage="com.google.android.frameworktest"
377 android:label="framework instrumentation test runner" /&gt;
378</pre>
379
380
381<a name="androidInstrumentationTestingCreatingTestCase"></a><h3>New InstrumentationTestCase</h3>
382
383<p> To create a new test case, write a class that extends <code>InstrumentationTestCase</code> in the same application as your test runner. The following snippet illustrates an example <code>ActivityTestCase</code> that tests an activity named <code>MyActivity</code>.</p>
384<pre class="prettify">
385public class ButtonPressTest extends ActivityTestCase&lt;MyActivity&gt; {
386
387 Button mLeftButton;
388
389 public ButtonPressTest() {
390 super("com.example", MyActivity.class);
391 }
392
393 @Override
394 public void setUp() throws Exception {
395 super.setUp();
396 mLeftButton = (Button) getActivity().findViewById(R.id.leftButton);
397 }
398
399 public void testFocusMovesToRight() throws Exception {
400 assertTrue(mLeftButton.hasFocus());
401 getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_DPAD_RIGHT);
402
403 Button rightButton = (Button) getActivity().findViewById(R.id.rightButton);
404 assertTrue(rightButton.hasFocus());
405 }
406
407 // could have several more tests...
408}
409</pre>
410
411
412<a name="androidInstrumentationFrameworkTestCase"></a><h3>Exploring a Test Case</h3>
413
414<p> The test case described in this section adds and tests a new Contact. Note that you can send intents, register intent receivers, etc. </p>
415<p><code>Instrumentation.java</code> has helper functions that send key events and strings, for example: </p>
416<ul>
417 <li><code>getInstrumentation()</code>: Returns the handle to the instrumentation </li>
418 <li><code>sendCharacterSync</code>: Sends a character. </li>
419 <li><code>sendStringSync</code>: Sends a string to an input box. </li>
420 <li><code>sendKeyDownUpSync</code>: Sends a specific keyevent. </li>
421 <li><code>sendTrackballEventSync</code>: Sends a trackball event.</li>
422</ul>
423<p> You can find the test case below at <code>device/tests/Contacts.</code></p>
424<pre class="prettify">
425private void addNewContact(String name, int star, int phoneType, String number, String label,
426 String email, int emailType){
427 ContentValues values = new ContentValues();
428 Uri phoneUri = null;
429 Uri emailUri = null;
430
431 values.put(Contacts.People.NAME, name);
432 values.put(Contacts.People.STARRED, star);
433
434 //Add Phone Numbers
435 Uri uri = mActivity.getContentResolver().insert(Contacts.People.CONTENT_URI, values);
436 phoneUri = Uri.withAppendedPath(uri, Contacts.People.Phones.CONTENT_DIRECTORY);
437
438 values.clear();
439 values.put(Contacts.Phones.TYPE, phoneType);
440 values.put(Contacts.Phones.NUMBER, number);
441 values.put(Contacts.Phones.LABEL, label);
442 mActivity.getContentResolver().insert(phoneUri, values);
443
444 //Add Email
445 emailUri = Uri.withAppendedPath(uri, ContactMethods.CONTENT_DIRECTORY);
446
447 values.clear();
448 values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
449 values.put(ContactMethods.DATA, email);
450 values.put(ContactMethods.LABEL, "");
451 values.put(ContactMethods.TYPE, emailType);
452 mActivity.getContentResolver().insert(emailUri, values);
453}
454
455
456 public void testAddSaveSingleContact(){
457 int previousCount = mActivity.getListView().getCount();
458 String message;
459
460 addNewContact(INPUT_NAME_1 + "1", "5435754532", "1" + INPUT_EMAIL_1, CONFIRM_OPTION);
461
462 message = "Added 1 to initial length=" + previousCount + ", but resulted with a count=" +
463 mActivity.getListView().getCount();
464 assertEquals(message, ++previousCount, mActivity.getListView().getCount());
465
466 // Check Content; Name; Num; Starred
467 assertEquals(INPUT_NAME_1 + "1", getTextFromView(0, android.R.id.text1));
468 assertEquals("5435754532", getTextFromView(0, android.R.id.text2));
469
470 //Check email is saved
471 //cursor = returnEmailCursorAtId("1");
472 Uri uri = Uri.parse("content://contacts/people/1");
473 uri = Uri.withAppendedPath(uri, ContactMethods.CONTENT_DIRECTORY);
474 Cursor cursor = mActivity.getContentResolver().query(uri, CONTACTS_COLUMNS, null, null, null);
475 assertTrue("returnEmailCursorAtId: Moving cursor to first row has failed", cursor.first());
476
477 int dataIndex = cursor.getColumnIndexOrThrow("data");
478 assertEquals("1" + INPUT_EMAIL_1, cursor.getString(dataIndex));
479 cursor.deactivate();
480}
481 </pre>
482
483
484<a name="androidTestingKindsofTests"></a><h3>Deciding Kinds of Tests to Write</h3>
485
486<p>Once you are bootstrapped with your test application, you can start writing tests. There are three of types of tests you may wish to write:</p>
487<p><ul>
488<li> <strong>TestCase</strong>: The standard junit test case.
489</li>
490<li> <strong>AndroidTestCase</strong>: A test case with access to a Context object that is injected for you by the instrumentation test runner.
491</li>
492<li> <strong>InstrumentationTestCase</strong>: A test case with access to an Instrumentation, which can be used to launch activities, content providers, send key events, etc.
493</li>
494</ul>
495</p>
496<p>The API Demos test suite includes examples of all three styles and can be used as a guideline for writing each type of test.</p>
497<p>There are two utility classes available for the most common uses of InstrumentationTestCase: ActivityTestCase and ProviderTestCase. See their javadoc for more information.
498</p>
499
500
501<a name="androidInstrumentationFrameworkTroubleshooting"></a><h2>Troubleshooting</h2>
502
503<p>If you run your test cases and nothing appears to happen, have a look at <code>adb logcat</code>. The following is a common problem:</p>
504<pre class="prettify">
505I/dalvikvm( 688): threadid=11: attached from native, name=Binder Thread #1
506I/dalvikvm( 688): threadid=13: attached from native, name=Binder Thread #2
507W/ActivityManager( 469): Unable to find instrumentation info for: ComponentInfo{com.google.android.browser_instrumentation/com.google.android.browser_instrumentation.BrowserWebkitLayoutInstrumentation}
508D/AndroidRuntime( 688): Shutting down VM
509E/AndroidRuntime( 688): ERROR: thread attach failed
510</pre>
511<p>It's possible that the instrumentation apk isn't installed on your device or that the package name is incorrect in the Manifest file. </p>