📄 instrumentation_testing.html
字号:
# Include all test java files.LOCAL_SRC_FILES := $(call all-java-files-under, src) # Notice that we don't have to include the src files of ApiDemos because, by# running the tests using an instrumentation targeting ApiDemos, we# automatically get all of its classes loaded into our environment. LOCAL_PACKAGE_NAME := ApiDemosTests LOCAL_INSTRUMENTATION_FOR := ApiDemos include $(BUILD_PACKAGE)</pre><a name="androidTestingContentManifest"></a><h3>Content of Manifest</h3><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><pre> # Add appropriate copyright banner here<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.samples.tests"> <uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /> <!-- This declares that this app uses the instrumentation test runner targeting the package of com.android.samples. To run the tests use the command: "adb shell am instrument -w com.android.samples.tests/android.test.InstrumentationTestRunner" --> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.android.samples" android:label="Tests for Api Demos."/> </manifest></pre> <p> </p> <p>The following snippet will prefix the <code>/android.test.InstrumentationTestRunner</code> when running tests from the command line:</p><pre> $ adb shell am instrument -w \ com.android.samples.tests/android.test.InstrumentationTestRunner</pre> <a name="androidInstrumentationTestingCreatingTestRunner"></a><h3>New Instrumentation TestRunner</h3><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><pre class="prettify">public class FrameworkInstrumentationTestRunner extends InstrumentationTestRunner { @Override public TestSuite getAllTests() { InstrumentationTestSuite suite = new InstrumentationTestSuite(this); suite.addTestSuite(FocusAfterRemovalTest.class); suite.addTestSuite(RequestFocusTest.class); suite.addTestSuite(RequestRectangleVisibleTest.class); return suite; } @Override public ClassLoader getLoader() { return FrameworkInstrumentationTestRunner.class.getClassLoader(); }}</pre><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><pre class="prettify"><uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /><instrumentation android:name="android.tests.FrameworkInstrumentationTestRunner" android:targetPackage="com.google.android.frameworktest" android:label="framework instrumentation test runner" /></pre> <a name="androidInstrumentationTestingCreatingTestCase"></a><h3>New InstrumentationTestCase</h3><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><pre class="prettify">public class ButtonPressTest extends ActivityTestCase<MyActivity> { Button mLeftButton; public ButtonPressTest() { super("com.example", MyActivity.class); } @Override public void setUp() throws Exception { super.setUp(); mLeftButton = (Button) getActivity().findViewById(R.id.leftButton); } public void testFocusMovesToRight() throws Exception { assertTrue(mLeftButton.hasFocus()); getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_DPAD_RIGHT); Button rightButton = (Button) getActivity().findViewById(R.id.rightButton); assertTrue(rightButton.hasFocus()); } // could have several more tests...}</pre><a name="androidInstrumentationFrameworkTestCase"></a><h3>Exploring a Test Case</h3><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><p><code>Instrumentation.java</code> has helper functions that send key events and strings, 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>: Sends 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="androidTestingKindsofTests"></a><h3>Deciding Kinds of Tests to Write</h3><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> <p><ul> <li> <strong>TestCase</strong>: The standard junit test case.</li> <li> <strong>AndroidTestCase</strong>: A test case with access to a Context object that is injected for you by the instrumentation test runner.</li> <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.</li> </ul> </p> <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><p>There are two utility classes available for the most common uses of InstrumentationTestCase: ActivityTestCase and ProviderTestCase. See their javadoc for more information.</p><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 #1I/dalvikvm( 688): threadid=13: attached from native, name=Binder Thread #2W/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 VME/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><p><span class="lh2"><a name="androidFooter"></a></span> </div> </div> <!-- end gc-pagecontent --> </div> <!-- end gooey wrapper --> </div> <!-- end codesearchresults --> <div id="gc-footer" dir="ltr"> <div class="text"> ©2008 Google<!-- - <a href="/">Code Home</a> - <a href="http://www.google.com/accounts/TOS">Site Terms of Service</a> - <a href="http://www.google.com/privacy.html">Privacy Policy</a> - <a href="/more">Site Directory</a> --></div> </div> <!-- end gc-footer --></div><!-- end gc-containter --><script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script><script type="text/javascript"> try { var pageTracker = _gat._getTracker("UA-18071-1"); pageTracker._setAllowAnchor(true); pageTracker._initData(); pageTracker._trackPageview(); } catch(e) {}</script><div id="jd-build-id"> v0.6 - 25 November 2008</div></div></div></div></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -