blob: 00c82481885b1bc8a744b39a336ce2b1643cc489 [file] [log] [blame]
David Warren5f6ca4f2009-04-30 17:11:58 -07001page.title=Instrumentation Testing
2pdk.version=1.0
3@jd:body
4
David Warren5c40a482009-06-05 15:11:21 -07005<div id="qv-wrapper">
6<div id="qv">
7<h2>In this document</h2>
David Warren5f6ca4f2009-04-30 17:11:58 -07008<a name="toc"/>
David Warren5c40a482009-06-05 15:11:21 -07009<ul>
10<li><a href="#androidInstrumentationTestingFramework">Instrumentation Framework</a></li>
11<li><a href="#androidInstrumentationFrameworkPlatform">Platform Test Suites</a></li>
12<li><a href="#androidInstrumentationFrameworkWritingRunning">Running Tests</a></li>
13<li><a href="#androidInstrumentationTestingCreating">Writing Tests</a></li>
14<li><a href="#troubleshooting">Troubleshooting</a></li>
15</ul>
16</div>
17</div>
David Warren5f6ca4f2009-04-30 17:11:58 -070018
19<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>
20<p>You should have a working knowledge of the following:</p>
21<ul>
22 <li> Android Application Framework</li>
23 <li> Using <code>adb</code>, <code>am</code> and various logging functionality </li>
24 <li> A brief understanding of the application of interest, that is, the names of the classes which handle the intents etc. </li>
25 <li> JUnit testing.</li>
26</ul>
27<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>
28
29
David Warren5c40a482009-06-05 15:11:21 -070030<a name="androidInstrumentationTestingFramework"></a><h3>Instrumentation Framework</h3>
David Warren5f6ca4f2009-04-30 17:11:58 -070031
32
33
David Warren5c40a482009-06-05 15:11:21 -070034<a name="androidInstrumentationTestingClasses"></a><h4>Classes</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -070035
36<p> The following classes help glue together <code>Instrumentation</code> with JUnit testing. </p>
37<table>
38 <tr>
39 <th scope="col">Class</th>
40 <th scope="col">Description</th></tr>
41 <tr>
42 <td valign="top"><code>InstrumentationTestCase</code></td>
43 <td valign="top">
44 <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>
45 </tr>
46 <tr>
47 <td valign="top"><code>InstrumentationTestRunner</code></td>
48 <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>
49 </tr>
50 <tr>
51 <td valign="top"><code>InstrumentationTestSuite</code></td>
52 <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>
53 </tr>
54</table>
55<p> Three additional base classes extend <code>InstrumentationTestCase</code> to allow you to test <code>Activity</code> and <code>Provider</code> classes:</p>
56<table>
57 <tr>
58 <th scope="col">Class</th>
59 <th scope="col">Description</th>
60 </tr>
61 <tr>
62 <td valign="top"><code>ActivityTestCase</code></td>
63 <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>
64 </tr>
65 <tr>
66 <td valign="top"><code>ServiceTestCase</code></td>
67 <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>
68 </tr>
69 <tr>
70 <td valign="top"><code>SingleLaunchActivityTestCase</code></td>
71 <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>
72 </tr>
73 <tr>
74 <td valign="top"><code>ProviderTestCase</code></td>
75 <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>
76 </tr>
77</table>
78
79
David Warren5c40a482009-06-05 15:11:21 -070080<a name="androidInstrumentationFrameworkamCommand"></a><h4>Understanding the am Command</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -070081
82<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>
83<pre class="prettify">
84&gt; adb shell am
85usage: am [start|instrument]
86 am start [-a &lt;ACTION&gt;] [-d &lt;DATA_URI&gt;] [-t &lt;MIME_TYPE&gt;]
87 [-c &lt;CATEGORY&gt; [-c &lt;CATEGORY&gt;] ...]
88 [-e &lt;EXTRA_KEY&gt; &lt;EXTRA_VALUE&gt; [-e &lt;EXTRA_KEY&gt; &lt;EXTRA_VALUE&gt; ...]
89 [-n &lt;COMPONENT&gt;] [-D] [&lt;URI&gt;]
90 am instrument [-e &lt;ARG_NAME&gt; &lt;ARG_VALUE&gt;] [-p &lt;PROF_FILE&gt;]
91 [-w] &lt;COMPONENT&gt;
92For example, to start the Contacts application you can use
93&gt; adb shell am start -n com.google.android.contacts/.ContactsActivity
94</pre>
95
96
David Warren5c40a482009-06-05 15:11:21 -070097<a name="androidInstrumentationFrameworkPlatform"></a><h3>Platform Test Suites</h3>
David Warren5f6ca4f2009-04-30 17:11:58 -070098
99<p>This section provides an overview for various unit and functional test cases that can be executed through the instrumentation framework.</p>
100
101
David Warren5c40a482009-06-05 15:11:21 -0700102<a name="androidTestingPlatformFramework"></a><h4>Framework Tests</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700103
104<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>
105
106
David Warren5c40a482009-06-05 15:11:21 -0700107<a name="androidTestingPlatformCoreLibrary"></a><h4>Core Library</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700108
109<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>
110
111
David Warren5c40a482009-06-05 15:11:21 -0700112<a name="androidInstrumentationFrameworkWritingRunning"></a><h3>Running Tests</h3>
David Warren5f6ca4f2009-04-30 17:11:58 -0700113
114<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>
115<ul>
116 <li> There should be a Makefile and an Android Manifest file. </li>
117 <li> Tests are located in <code>tests/Contacts/src/com/google/android/contactstests</code>. </li>
118 <li> The Instrumentation Test Runner is located at <code>tests/Contacts/src/com/google/android/contactstests/functional/ContactsInstrumentationTestRunner.java</code>.</li>
119</ul>
120<p>Suppose you have a makefile with <code>Contactstests</code> as the target. </p>
121<ul>
122 <li> <code>make Contactstests</code>: Compiles the test cases. </li>
123 <li> <code>adb install Contactstests.apk</code>: Installs the apk on the device. </li>
124 <li> Use the adb shell <code>am</code> command to run them. </li>
125</ul>
126<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>
127<pre class="prettify">
128$ adb shell am instrument -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner
129INSTRUMENTATION_RESULT: test results:=.......F.......
130Time: 6.837
131There was 1 failure:
1321) testSetUpConditions(com.google.android.frameworktest.tests.focus.RequestFocusTest)junit.framework.AssertionFailedError: requestFocus() should work from onCreate.
133 at com.google.android.frameworktest.tests.focus.RequestFocusTest.testSetUpConditions(RequestFocusTest.java:66)
134 at java.lang.reflect.Method.invokeNative(Native Method)
135 at android.test.InstrumentationTestSuite.runTest(InstrumentationTestSuite.java:73)
136 at android.test.InstrumentationTestSuite.runTest(InstrumentationTestSuite.java:73)
137 at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:151)
138 at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1088)
139
140FAILURES!!!
141Tests run: 14, Failures: 1, Errors: 0
142
143&lt;RETURN&gt; to continue
144
145INSTRUMENTATION_CODE: -1
146$
147</pre>
148
149
David Warren5c40a482009-06-05 15:11:21 -0700150<a name="androidInstrumentationTestingRunningAll"></a><h4>All Tests with Default TestRunner behavior</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700151
152<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).
153</p>
154<pre>
155$ adb shell am instrument -w \
156 com.android.samples.tests/android.test.InstrumentationTestRunner
157
158INSTRUMENTATION_RESULT: Test results for InstrumentationTestRunner=..........
159Time: 2.317
160
161OK (10 tests)
162
163
164INSTRUMENTATION_CODE: -1
165</pre>
166
167
David Warren5c40a482009-06-05 15:11:21 -0700168<a name="androidTestingTestSinglePakcage"></a><h4>Running all Tests Under Single Package</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700169
170<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>
171<pre>
172$ adb shell am instrument -w \
173 -e package com.android.samples.view \
174 com.android.samples.tests/android.test.InstrumentationTestRunner
175INSTRUMENTATION_RESULT: Test results for InstrumentationTestRunner=........
176Time: 1.587
177
178OK (8 tests)
179</pre>
180
181
David Warren5c40a482009-06-05 15:11:21 -0700182<a name="androidTestingSingleTestSuite"></a><h4>Running a Single Test Suite</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700183
184<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>
185
186<pre>
187$ adb shell am instrument -w \
188 -e class com.android.samples.AllTests \
189 com.android.samples.tests/android.test.InstrumentationTestRunner
190
191INSTRUMENTATION_RESULT: Test results for AllTests=..........
192Time: 2.286
193
194OK (10 tests)
195
196
197INSTRUMENTATION_CODE: -1
198</pre>
199
200
David Warren5c40a482009-06-05 15:11:21 -0700201<a name="androidInstrumentationTestingRunningSingleTestCase"></a><h4>A Single Test Case</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700202
203<pre>
204$ adb shell am instrument -w \
205 -e class com.android.samples.view.Focus2ActivityTest \
206 com.android.samples.tests/android.test.InstrumentationTestRunner
207
208INSTRUMENTATION_RESULT: Test results for Focus2ActivityTest=....
209Time: 1.359
210
211OK (4 tests)
212
213
214INSTRUMENTATION_CODE: -1
215</pre>
216
217
David Warren5c40a482009-06-05 15:11:21 -0700218<a name="androidInstrumentationTestingRunningSingleTest"></a><h4>A Single Test</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700219
220<pre>
221$ adb shell am instrument -w \
222 -e class com.android.samples.view.Focus2ActivityTest#testGoingLeftFromRightButtonGoesToCenter \
223 com.android.samples.tests/android.test.InstrumentationTestRunner
224
225INSTRUMENTATION_RESULT: Test results for Focus2ActivityTest=.
226Time: 0.51
227
228OK (1 test)
229
230
231INSTRUMENTATION_CODE: -1
232</pre>
233
234
David Warren5c40a482009-06-05 15:11:21 -0700235<a name="androidTestingDebugging"></a><h4>Attaching a debugger to your test</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700236
237<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
238command line. This causes the test runner to stop and wait for the debugger just before calling your <code>setUp()</code> method. For example,</p>
239
240<pre>
241$ adb shell am instrument -w \
242 -e debug true \
243 com.android.samples.tests/android.test.InstrumentationTestRunner
244</pre>
245
246
David Warren5c40a482009-06-05 15:11:21 -0700247<a name="androidInstrumentationTestingCreating"></a><h3>Writing Tests</h3>
David Warren5f6ca4f2009-04-30 17:11:58 -0700248
249<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>
250
251
David Warren5c40a482009-06-05 15:11:21 -0700252<a name="androidTestingLocationFiles"></a><h4>Location of Files</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700253
254<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>
255<p>Files are located within a <code>tests</code> directory found in the root directory:</p>
256<pre>
257$ find samples/ApiDemos/tests
258samples/ApiDemos/tests
259samples/ApiDemos/tests/Android.mk
260samples/ApiDemos/tests/AndroidManifest.xml
261samples/ApiDemos/tests/src
262samples/ApiDemos/tests/src/com
263samples/ApiDemos/tests/src/com/google
264samples/ApiDemos/tests/src/com/google/android
265samples/ApiDemos/tests/src/com/google/android/samples
266samples/ApiDemos/tests/src/com/google/android/samples/AllTests.java
267samples/ApiDemos/tests/src/com/google/android/samples/ApiDemosTest.java
268samples/ApiDemos/tests/src/com/google/android/samples/os
269samples/ApiDemos/tests/src/com/google/android/samples/os/MorseCodeConverterTest.java
270samples/ApiDemos/tests/src/com/google/android/samples/view
271samples/ApiDemos/tests/src/com/google/android/samples/view/Focus2ActivityTest.java
272samples/ApiDemos/tests/src/com/google/android/samples/view/Focus2AndroidTest.java
273</pre>
274
275
David Warren5c40a482009-06-05 15:11:21 -0700276<a name="androidTestingContentMakefile"></a><h4>Contents of makefile</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700277
278<p>The contents of the makefile are similar to a normal application with the addition of a <code>LOCAL_INSTRUMENTATION_FOR</code> declaration.<p />
279<pre>
280# Add appropriate copyright banner here
281LOCAL_PATH:= $(call my-dir)
282include $(CLEAR_VARS)
283
284# We only want this apk build for tests.
285LOCAL_MODULE_TAGS := tests
286
287# Include all test java files.
288LOCAL_SRC_FILES := $(call all-java-files-under, src)
289
290# Notice that we don't have to include the src files of ApiDemos because, by
291# running the tests using an instrumentation targeting ApiDemos, we
292# automatically get all of its classes loaded into our environment.
293
294LOCAL_PACKAGE_NAME := ApiDemosTests
295
296LOCAL_INSTRUMENTATION_FOR := ApiDemos
297
298include $(BUILD_PACKAGE)
299</pre>
300
301
David Warren5c40a482009-06-05 15:11:21 -0700302<a name="androidTestingContentManifest"></a><h4>Content of Manifest</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700303
304<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>
305<pre>
306# Add appropriate copyright banner here
307&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
308 package="com.android.samples.tests"&gt;
309
310 &lt;uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /&gt;
311
312 &lt;!--
313 This declares that this app uses the instrumentation test runner targeting
314 the package of com.android.samples. To run the tests use the command:
315 "adb shell am instrument -w com.android.samples.tests/android.test.InstrumentationTestRunner"
316 --&gt;
317 &lt;instrumentation android:name="android.test.InstrumentationTestRunner"
318 android:targetPackage="com.android.samples"
319 android:label="Tests for Api Demos."/&gt;
320
321&lt;/manifest&gt;
322</pre>
323<p>&nbsp;</p>
324<p>The following snippet will prefix the <code>/android.test.InstrumentationTestRunner</code> when running tests from the command line:</p>
325<pre>
326$ adb shell am instrument -w \
327 com.android.samples.tests/android.test.InstrumentationTestRunner
328</pre>
329
330
David Warren5c40a482009-06-05 15:11:21 -0700331<a name="androidInstrumentationTestingCreatingTestRunner"></a><h4>New Instrumentation TestRunner</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700332
333<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>
334<pre class="prettify">
335public class FrameworkInstrumentationTestRunner extends InstrumentationTestRunner {
336
337 @Override
338 public TestSuite getAllTests() {
339 InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
340
341 suite.addTestSuite(FocusAfterRemovalTest.class);
342 suite.addTestSuite(RequestFocusTest.class);
343 suite.addTestSuite(RequestRectangleVisibleTest.class);
344 return suite;
345 }
346
347 @Override
348 public ClassLoader getLoader() {
349 return FrameworkInstrumentationTestRunner.class.getClassLoader();
350 }
351}
352</pre>
353<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>
354<pre class="prettify">
355&lt;uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /&gt;
356
357&lt;instrumentation android:name="android.tests.FrameworkInstrumentationTestRunner"
358 android:targetPackage="com.google.android.frameworktest"
359 android:label="framework instrumentation test runner" /&gt;
360</pre>
361
362
David Warren5c40a482009-06-05 15:11:21 -0700363<a name="androidInstrumentationTestingCreatingTestCase"></a><h4>New InstrumentationTestCase</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700364
365<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>
366<pre class="prettify">
367public class ButtonPressTest extends ActivityTestCase&lt;MyActivity&gt; {
368
369 Button mLeftButton;
370
371 public ButtonPressTest() {
372 super("com.example", MyActivity.class);
373 }
374
375 @Override
376 public void setUp() throws Exception {
377 super.setUp();
378 mLeftButton = (Button) getActivity().findViewById(R.id.leftButton);
379 }
380
381 public void testFocusMovesToRight() throws Exception {
382 assertTrue(mLeftButton.hasFocus());
383 getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_DPAD_RIGHT);
384
385 Button rightButton = (Button) getActivity().findViewById(R.id.rightButton);
386 assertTrue(rightButton.hasFocus());
387 }
388
389 // could have several more tests...
390}
391</pre>
392
393
David Warren5c40a482009-06-05 15:11:21 -0700394<a name="androidInstrumentationFrameworkTestCase"></a><h4>Exploring a Test Case</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700395
396<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>
397<p><code>Instrumentation.java</code> has helper functions that send key events and strings, for example: </p>
398<ul>
399 <li><code>getInstrumentation()</code>: Returns the handle to the instrumentation </li>
400 <li><code>sendCharacterSync</code>: Sends a character. </li>
401 <li><code>sendStringSync</code>: Sends a string to an input box. </li>
402 <li><code>sendKeyDownUpSync</code>: Sends a specific keyevent. </li>
403 <li><code>sendTrackballEventSync</code>: Sends a trackball event.</li>
404</ul>
405<p> You can find the test case below at <code>device/tests/Contacts.</code></p>
406<pre class="prettify">
407private void addNewContact(String name, int star, int phoneType, String number, String label,
408 String email, int emailType){
409 ContentValues values = new ContentValues();
410 Uri phoneUri = null;
411 Uri emailUri = null;
412
413 values.put(Contacts.People.NAME, name);
414 values.put(Contacts.People.STARRED, star);
415
416 //Add Phone Numbers
417 Uri uri = mActivity.getContentResolver().insert(Contacts.People.CONTENT_URI, values);
418 phoneUri = Uri.withAppendedPath(uri, Contacts.People.Phones.CONTENT_DIRECTORY);
419
420 values.clear();
421 values.put(Contacts.Phones.TYPE, phoneType);
422 values.put(Contacts.Phones.NUMBER, number);
423 values.put(Contacts.Phones.LABEL, label);
424 mActivity.getContentResolver().insert(phoneUri, values);
425
426 //Add Email
427 emailUri = Uri.withAppendedPath(uri, ContactMethods.CONTENT_DIRECTORY);
428
429 values.clear();
430 values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
431 values.put(ContactMethods.DATA, email);
432 values.put(ContactMethods.LABEL, "");
433 values.put(ContactMethods.TYPE, emailType);
434 mActivity.getContentResolver().insert(emailUri, values);
435}
436
437
438 public void testAddSaveSingleContact(){
439 int previousCount = mActivity.getListView().getCount();
440 String message;
441
442 addNewContact(INPUT_NAME_1 + "1", "5435754532", "1" + INPUT_EMAIL_1, CONFIRM_OPTION);
443
444 message = "Added 1 to initial length=" + previousCount + ", but resulted with a count=" +
445 mActivity.getListView().getCount();
446 assertEquals(message, ++previousCount, mActivity.getListView().getCount());
447
448 // Check Content; Name; Num; Starred
449 assertEquals(INPUT_NAME_1 + "1", getTextFromView(0, android.R.id.text1));
450 assertEquals("5435754532", getTextFromView(0, android.R.id.text2));
451
452 //Check email is saved
453 //cursor = returnEmailCursorAtId("1");
454 Uri uri = Uri.parse("content://contacts/people/1");
455 uri = Uri.withAppendedPath(uri, ContactMethods.CONTENT_DIRECTORY);
456 Cursor cursor = mActivity.getContentResolver().query(uri, CONTACTS_COLUMNS, null, null, null);
457 assertTrue("returnEmailCursorAtId: Moving cursor to first row has failed", cursor.first());
458
459 int dataIndex = cursor.getColumnIndexOrThrow("data");
460 assertEquals("1" + INPUT_EMAIL_1, cursor.getString(dataIndex));
461 cursor.deactivate();
462}
463 </pre>
464
465
David Warren5c40a482009-06-05 15:11:21 -0700466<a name="androidTestingKindsofTests"></a><h4>Deciding Kinds of Tests to Write</h4>
David Warren5f6ca4f2009-04-30 17:11:58 -0700467
468<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>
469<p><ul>
470<li> <strong>TestCase</strong>: The standard junit test case.
471</li>
472<li> <strong>AndroidTestCase</strong>: A test case with access to a Context object that is injected for you by the instrumentation test runner.
473</li>
474<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.
475</li>
476</ul>
477</p>
478<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>
479<p>There are two utility classes available for the most common uses of InstrumentationTestCase: ActivityTestCase and ProviderTestCase. See their javadoc for more information.
480</p>
481
482
David Warren5c40a482009-06-05 15:11:21 -0700483<a name="troubleshooting"></a><h3>Troubleshooting</h3>
David Warren5f6ca4f2009-04-30 17:11:58 -0700484
485<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>
486<pre class="prettify">
487I/dalvikvm( 688): threadid=11: attached from native, name=Binder Thread #1
488I/dalvikvm( 688): threadid=13: attached from native, name=Binder Thread #2
489W/ActivityManager( 469): Unable to find instrumentation info for: ComponentInfo{com.google.android.browser_instrumentation/com.google.android.browser_instrumentation.BrowserWebkitLayoutInstrumentation}
490D/AndroidRuntime( 688): Shutting down VM
491E/AndroidRuntime( 688): ERROR: thread attach failed
492</pre>
493<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>