page.title=Instrumentation Framework
@jd:body

<p>This document describes how to use the Android Instrumentation Framework to write test cases. You should have a working knowledge of the following:</p>
<ul>
  <li> Android Application Framework </li>
  <li> Using <code>adb</code>, <code>am</code> and various logging functionality </li>
  <li> A brief understanding of the application of interest, that is, he names of the classes which handle the intents etc. </li>
  <li> Junit testing. </li>
</ul>
<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>

<p>This document covers these topics:</p>

<ul>
<li><a href="#androidInstrumentationFrameworkamCommand">Understanding the am Command</a></li>
<li><a href="#androidInstrumentationFrameworkWritingRunning">Writing and Running Test Cases</a></li>
<li><a href="#androidInstrumentationFrameworkTestCase">Exploring a Test Case</a></li>
<li><a href="#androidInstrumentationFrameworkTroubleshooting">Troubleshooting</a></li>
</ul>

<a name="androidInstrumentationFrameworkamCommand"></a><h2>Understanding the am Command</h2>

<p><code>am</code> is used to start and instrument activities using the adb shell command, as shown in the snippet below:</p>
<pre class="prettify">
&gt; adb shell am
usage: am [start|instrument]
       am start [-a &lt;ACTION&gt;] [-d &lt;DATA_URI&gt;] [-t &lt;MIME_TYPE&gt;]
                [-c &lt;CATEGORY&gt; [-c &lt;CATEGORY&gt;] ...]
                [-e &lt;EXTRA_KEY&gt; &lt;EXTRA_VALUE&gt; [-e &lt;EXTRA_KEY&gt; &lt;EXTRA_VALUE&gt; ...]
                [-n &lt;COMPONENT&gt;] [-D] [&lt;URI&gt;]
       am instrument [-e &lt;ARG_NAME&gt; &lt;ARG_VALUE&gt;] [-p &lt;PROF_FILE&gt;]
                [-w] &lt;COMPONENT&gt;
For example, to start the Contacts application you can use
&gt; adb shell am start -n com.google.android.contacts/.ContactsActivity
</pre>


<a name="androidInstrumentationFrameworkWritingRunning"></a><h2>Writing and Running Test Cases</h2>

<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>
<ul>
  <li> There should be a Makefile and an Android Manifest file. </li>
  <li> Tests are located in <code>tests/Contacts/src/com/google/android/contactstests</code>. </li>
  <li> The Instrumentation Test Runner is located at <code>tests/Contacts/src/com/google/android/contactstests/functional/ContactsInstrumentationTestRunner.java</code>.</li>
</ul>
<p>Suppose you have a makefile with <code>Contactstests</code> as the target. </p>
<ul>
  <li> <code>make Contactstests</code>: Compiles the test cases. </li>
  <li> <code>adb install Contactstests.apk</code>: Installs the apk on the device. </li>
  <li> Use the adb shell <code>am</code> command to run them. </li>
</ul>
<p> For options and other details, please see <a href="inst-testing.html">Instrumentation Testing</a>.</p>


<a name="androidInstrumentationFrameworkTestCase"></a><h2>Exploring a Test Case</h2>

<p> The test case described in this section adds and tests a new Contact. Note that you can send intents, register broadcast receivers, etc. </p>
<p><code>Instrumentation.java</code> has helper functions that send key events and string, for example: </p>
<ul>
  <li><code>getInstrumentation()</code>: Returns the handle to the instrumentation </li>
  <li><code>sendCharacterSync</code>: Sends a character. </li>
  <li><code>sendStringSync</code>: Sends a string to an input box. </li>
  <li><code>sendKeyDownUpSync</code>: Sends a specific keyevent. </li>
  <li><code>sendTrackballEventSync</code>: Send a trackball event.</li>
</ul>
<p> You can find the test case below at <code>device/tests/Contacts.</code></p>
<pre class="prettify">
private void addNewContact(String name, int star, int phoneType, String number, String label,
		String email, int emailType){
	ContentValues values = new ContentValues();
	Uri phoneUri = null;
	Uri emailUri = null;

	values.put(Contacts.People.NAME, name);
	values.put(Contacts.People.STARRED, star);

	//Add Phone Numbers
	Uri uri = mActivity.getContentResolver().insert(Contacts.People.CONTENT_URI, values);
	phoneUri = Uri.withAppendedPath(uri, Contacts.People.Phones.CONTENT_DIRECTORY);

	values.clear();
	values.put(Contacts.Phones.TYPE, phoneType);
	values.put(Contacts.Phones.NUMBER, number);
	values.put(Contacts.Phones.LABEL, label);
	mActivity.getContentResolver().insert(phoneUri, values);

	//Add Email
	emailUri = Uri.withAppendedPath(uri, ContactMethods.CONTENT_DIRECTORY);

	values.clear();
	values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
	values.put(ContactMethods.DATA, email);
	values.put(ContactMethods.LABEL, "");
	values.put(ContactMethods.TYPE, emailType);
	mActivity.getContentResolver().insert(emailUri, values);
}


 public void testAddSaveSingleContact(){
	int previousCount = mActivity.getListView().getCount();
	String message;

	addNewContact(INPUT_NAME_1 + "1", "5435754532", "1" + INPUT_EMAIL_1, CONFIRM_OPTION);

	message = "Added 1 to initial length=" + previousCount + ", but resulted with a count=" +
		mActivity.getListView().getCount();
	assertEquals(message, ++previousCount, mActivity.getListView().getCount());

	// Check Content; Name; Num; Starred
	assertEquals(INPUT_NAME_1 + "1", getTextFromView(0, android.R.id.text1));
	assertEquals("5435754532", getTextFromView(0, android.R.id.text2));

	//Check email is saved
	//cursor = returnEmailCursorAtId("1");
	Uri uri = Uri.parse("content://contacts/people/1");
	uri = Uri.withAppendedPath(uri, ContactMethods.CONTENT_DIRECTORY);
	Cursor cursor = mActivity.getContentResolver().query(uri, CONTACTS_COLUMNS, null, null, null);
	assertTrue("returnEmailCursorAtId: Moving cursor to first row has failed", cursor.first());

	int dataIndex = cursor.getColumnIndexOrThrow("data");
	assertEquals("1" + INPUT_EMAIL_1, cursor.getString(dataIndex));
	cursor.deactivate();
}
	</pre>


<a name="androidInstrumentationFrameworkTroubleshooting"></a><h2>Troubleshooting</h2>

<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>
<pre class="prettify">
I/dalvikvm(  688): threadid=11: attached from native, name=Binder Thread #1
I/dalvikvm(  688): threadid=13: attached from native, name=Binder Thread #2
W/ActivityManager(  469): Unable to find instrumentation info for: ComponentInfo{com.google.android.browser_instrumentation/com.google.android.browser_instrumentation.BrowserWebkitLayoutInstrumentation}
D/AndroidRuntime(  688): Shutting down VM
E/AndroidRuntime(  688): ERROR: thread attach failed
</pre>		
<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>

