blob: 7e58ce4469e6e7c3baff19c136af9012b8df6423 [file] [log] [blame]
The Android Open Source Project5c118522008-10-21 07:00:00 -07001
2<html>
3<head>
4<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
5<title>Android - Instrumentation Testing</title>
6<script src="http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key=internal-codesite" type="text/javascript"></script>
7<script src="http://code.google.com/js/jquery.js" type="text/javascript"></script>
8<script type="text/javascript">var _tocPath_ = 'http://code.google.com/android/_toc.ezt';</script>
9<script src="http://code.google.com/js/codesite.pack.01312008.js" type="text/javascript"></script>
10<link href="http://code.google.com/css/codesite.pack.01312008.css" type="text/css" rel="stylesheet">
11</link>
12
13<!--[if IE]><link rel="stylesheet" type="text/css" href="/css/iehacks.css" /><![endif]-->
14<script src="http://code.google.com/android/assets/search_autocomplete.js"></script>
15<link rel="stylesheet" type="text/css" href="http://code.google.com/css/semantic_headers.css" />
16<link rel="stylesheet" type="text/css" href="http://code.google.com/android/assets/style.css" />
17<script>
18 jQuery(document).ready(function() {
19 jQuery("pre").addClass("prettyprint");
20 });
21 </script>
22<style type="text/css">
23<!--
24h1,h2,h3 {
25 color: #000000;
26}
27-->
28</style>
29</head>
30<body class="gc-documentation">
31<div id="gc-container">
32<a name="top"></a>
33<div id="skipto"> </div>
34<div id="langpref">
35 <!--<a class="dropdown" href="/">English</a> <span>|</span> <a href="/more/">Site Directory</a> -->
36</div>
37<div id="gc-header">
38 <div id="logo"><a href="http://code.google.com/android/index.html"><img src="http://code.google.com/android/images/logo_android.gif" alt="Android"/></a></div>
39 <div id="search" style="inline">
40 <div id="searchForm" class="searchForm" style="height: 44px;">
41 <!--previously form was here-->
42 </div>
43 <!-- end searchForm -->
44 <noscript>
45 <style type="text/css">
46 .searchForm {
47 display : none !important;
48 }
49 .searchForm2 {
50 display : inline !important;
51 }
52 </style>
53 </noscript>
54 <div id="searchForm2" class="searchForm2" style="display:none">
55 <form id="searchbox_001456098540849067467:6whlsytkdqg" action="http://www.google.com/cse">
56 <input type="hidden" name="cx" value="001456098540849067467:6whlsytkdqg" />
57 <input type="hidden" name="cof" value="FORID:0" />
58 <input type="text" name="q" maxlength="2048" size="41" autocomplete="off" title="Google Code Search"/>
59 <input type="submit" name="sa" value="Search" title="Search"/>
60 <br/>
61 <div class="greytext">e.g. "ajax apis" or "open source"</div>
62 </form>
63 </div>
64 <!-- end searchForm2 -->
65 </div>
66 <!-- end search -->
67</div>
68<!-- end gc-header -->
69<div id="searchControl" class="search-control"></div>
70<!--[if IE]><iframe id="backiFrame" name="backiFrame" src='/dummy.html' style="display:none"></iframe><![endif]-->
71<div id="codesiteContent">
72<a name="gc-topnav-anchor"></a>
73<div id="gc-topnav">
74 <h1>Android Platform Development Kit</h1>
75 <ul class="gc-topnav-tabs">
76 <li id="sdk_link"> <a href="http://code.google.com/android/index.html" title="Android Software Development Kit">SDK</a> </li>
77 <li id="docs_link"> <a href="index.html" title="Official Android documentation">Docs</a> </li>
78 <li id="faq_link"> <a href="http://code.google.com/android/kb/index.html" title="Answers to frequently asked questions about Android">FAQ</a> </li>
79 <li> <a href="http://android-developers.blogspot.com/" title="Official Android blog">Blog</a> </li>
80 <li> <a href="http://code.google.com/android/groups.html" title="Android developer forum">Group</a> </li>
81 <li> <a href="http://code.google.com/android/terms.html" title="Android terms of service">Terms</a> </li>
82 <li> <a href="mailto:android-pdk-feedback@google.com?subject=PDK%20Feedback&body=(filed%20from:%20instrumentation_testing.html%20v0.3%20-%209%20June%202008)%0D%0A%0D%0ASUMMARY:%0D%0A%0D%0A%0D%0A%0D%0ASTEPS%20TO%20REPRODUCE:%0D%0A%0D%0A%0D%0A%0D%0AADDITIONAL%20NOTES:">Report a Problem</a> </li>
83 </ul>
84</div>
85<!-- end gc-topnav -->
86<div class="g-section g-tpl-180">
87<a name="gc-toc"></a>
88<div class="g-unit g-first" id="gc-toc">
89 <ul>
90 <li>
91 <h1><a href="index.html">Documentation</a></h1>
92 <ul>
93 <li> <strong>Introduction</strong>
94 <ul>
95 <li><a href="system_requirements.html">Device Requirements</a></li>
96 </ul>
97 </li>
98 <li> <strong>Dev Environment Setup</strong>
99 <ul>
100 <li><a href="source_setup_guide.html">Host System Setup</a></li>
101 <li><a href="getting_source_code.html">Getting Source Code</a></li>
102 <li> <a href="intro_source_code.html">Source Code Overview</a></li>
103 <li><a href="build_system.html">Build System</a></li>
104 </ul>
105 </li>
106 <li> <strong>Basic Bring up</strong>
107 <ul>
108 <li><a href="build_new_device.html">Building New Device</a></li>
109 <li><a href="bring_up.html">Bring up</a></li>
110 <li><a href="keymaps_keyboard_input.html">Keymaps and Keyboard</a></li>
111 <li><a href="display_drivers.html">Display Drivers</a></li>
112 </ul>
113 </li>
114 <li> <strong>Multimedia</strong>
115 <ul>
116 <li><a href="audio_sub_system.html">Audio Subsystem</a></li>
117 </ul>
118 </li>
119 <li> <strong>Power Management</strong>
120 <ul>
121 <li><a href="power_management.html">Power Management</a></li>
122 </ul>
123 </li>
124 <li> <strong>Telephony</strong>
125 <ul>
126 <li><a href="telephony.html">Radio Interface Layer</a></li>
127 </ul>
128 </li>
129 <li> <strong>Testing</strong>
130 <ul>
131 <li><a href="instrumentation_framework.html">Instrumentation Framework</a></li>
132 <li><a href="instrumentation_testing.html">Instrumentation Testing</a></li>
133 </ul>
134 </li>
135 </ul>
136 </li>
137 </ul>
138</div>
139<a name="gc-pagecontent"></a>
140<div class="g-unit" id="gc-pagecontent">
141<div id="jd-content">
142<div class="jd-descr">
143
144
145<a name="androidTitleInstrumentationTesting"></a><h1>Instrumentation Testing</h1>
146
147
148
149<a name="toc"/>
150<div style="padding:10px">
151<a href="#androidInstrumentationTestingIntro">Introduction</a><br/>
152<a href="#androidInstrumentationTestingClasses">Classes</a><br/>
153<a href="#androidInstrumentationTestingRunning">Running Tests</a><br/><div style="padding-left:40px">
154
155<a href="#androidInstrumentationTestingRunningAll">All Tests</a><br/>
156<a href="#androidInstrumentationTestingRunningSingleTestCase">A Single Test Case</a><br/>
157<a href="#androidInstrumentationTestingRunningSingleTest">A Single Test</a><br/></div>
158<a href="#androidInstrumentationTestingCreating">Creating Tests</a><br/><div style="padding-left:40px">
159
160<a href="#androidInstrumentationTestingCreatingTestRunner">New Instrumentation TestRunner</a><br/>
161<a href="#androidInstrumentationTestingCreatingTestCase">New InstrumentationTestCase</a><br/></div>
162<a href="#androidInstrumentationAliases">Aliases for Running Framework Instrumentation Tests</a><br/></div></font></div>
163
164<a name="androidInstrumentationTestingIntro"></a><h2>Introduction</h2>
165
166<p>Sometimes you may want to manually interact with your applications to verify that a particular feature or behavior is working properly; why not automate this verification with a JUnit TestCase that can instrument applications?</p>
167<p>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>
168
169
170<a name="androidInstrumentationTestingClasses"></a><h2>Classes</h2>
171
172<p> The following classes help glue together <code>Instrumentation</code> with JUnit testing. </p>
173<table>
174 <tr>
175 <th scope="col">Class</th>
176 <th scope="col">Description</th></tr>
177 <tr>
178 <td valign="top"><code>InstrumentationTestCase</code></td>
179 <td valign="top">
180 <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>
181 </td>
182 </tr>
183 <tr>
184 <td valign="top"><code>InstrumentationTestRunner</code></td>
185 <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>
186 </tr>
187 <tr>
188 <td valign="top"><code>InstrumentationTestSuite</code></td>
189 <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>
190 </tr>
191</table>
192<p> Three additional base classes extend <code>InstrumentationTestCase</code> to allow you to test <code>Activity</code> and <code>Provider</code> classes:</p>
193<table>
194 <tr>
195 <th scope="col">Class</th>
196 <th scope="col">Description</th>
197 </tr>
198 <tr>
199 <td valign="top"><code>ActivityTestCase</code></td>
200 <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>
201 </tr>
202 <tr>
203 <td valign="top"><code>SingleLaunchActivityTestCase</code></td>
204 <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>
205 </tr>
206 <tr>
207 <td valign="top"><code>ProviderTestCase</code></td>
208 <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>
209 </tr>
210</table>
211
212
213<a name="androidInstrumentationTestingRunning"></a><h2>Running Tests</h2>
214
215<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>
216<pre class="prettify">
217$ adb shell am instrument -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner
218INSTRUMENTATION_RESULT: test results:=.......F.......
219Time: 6.837
220There was 1 failure:
2211) testSetUpConditions(com.google.android.frameworktest.tests.focus.RequestFocusTest)junit.framework.AssertionFailedError: requestFocus() should work from onCreate.
222 at com.google.android.frameworktest.tests.focus.RequestFocusTest.testSetUpConditions(RequestFocusTest.java:66)
223 at java.lang.reflect.Method.invokeNative(Native Method)
224 at android.test.InstrumentationTestSuite.runTest(InstrumentationTestSuite.java:73)
225 at android.test.InstrumentationTestSuite.runTest(InstrumentationTestSuite.java:73)
226 at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:151)
227 at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1088)
228
229FAILURES!!!
230Tests run: 14, Failures: 1, Errors: 0
231
232&lt;RETURN&gt; to continue
233
234INSTRUMENTATION_CODE: -1
235$
236</pre>
237
238
239<a name="androidInstrumentationTestingRunningAll"></a><h3>All Tests</h3>
240
241<pre class="prettify">
242$ adb shell am instrument -w MyInstrumentationTestRunner
243</pre>
244
245
246<a name="androidInstrumentationTestingRunningSingleTestCase"></a><h3>A Single Test Case</h3>
247
248<pre class="prettify">
249$ adb shell am instrument \
250 -e class MyInstrumentationTestCase \
251 -w MyInstrumentationTestRunner
252</pre>
253
254
255<a name="androidInstrumentationTestingRunningSingleTest"></a><h3>A Single Test</h3>
256
257<pre class="prettify">
258$ adb shell am instrument \
259 -e class MyInstrumentationTestCase#myTestMethod \
260 -w MyInstrumentationTestRunner
261</pre>
262
263
264<a name="androidInstrumentationTestingCreating"></a><h2>Creating Tests</h2>
265
266
267
268<a name="androidInstrumentationTestingCreatingTestRunner"></a><h3>New Instrumentation TestRunner</h3>
269
270<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>
271<pre class="prettify">
272public class FrameworkInstrumentationTestRunner extends InstrumentationTestRunner {
273
274 @Override
275 public TestSuite getAllTests() {
276 InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
277
278 suite.addTestSuite(FocusAfterRemovalTest.class);
279 suite.addTestSuite(RequestFocusTest.class);
280 suite.addTestSuite(RequestRectangleVisibleTest.class);
281 return suite;
282 }
283
284 @Override
285 public ClassLoader getLoader() {
286 return FrameworkInstrumentationTestRunner.class.getClassLoader();
287 }
288}
289</pre>
290<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>
291<pre class="prettify">
292&lt;uses-permission android:name="android.permission.RUN_INSTRUMENTATION" /&gt;
293
294&lt;instrumentation android:name="android.tests.FrameworkInstrumentationTestRunner"
295 android:targetPackage="com.google.android.frameworktest"
296 android:label="framework instrumentation test runner" /&gt;
297</pre>
298
299
300<a name="androidInstrumentationTestingCreatingTestCase"></a><h3>New InstrumentationTestCase</h3>
301
302<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>
303<pre class="prettify">
304public class ButtonPressTest extends ActivityTestCase&lt;MyActivity&gt; {
305
306 Button mLeftButton;
307
308 public ButtonPressTest() {
309 super("com.example", MyActivity.class);
310 }
311
312 @Override
313 public void setUp() throws Exception {
314 super.setUp();
315 mLeftButton = (Button) getActivity().findViewById(R.id.leftButton);
316 }
317
318 public void testFocusMovesToRight() throws Exception {
319 assertTrue(mLeftButton.hasFocus());
320 getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_DPAD_RIGHT);
321
322 Button rightButton = (Button) getActivity().findViewById(R.id.rightButton);
323 assertTrue(rightButton.hasFocus());
324 }
325
326 // could have several more tests...
327}
328</pre>
329
330
331<a name="androidInstrumentationAliases"></a><h2>Aliases for Running Framework Instrumentation Tests</h2>
332
333<pre class="prettify">
334# compiles and installs FrameworkTests
335alias deploytests="(cd tests/FrameworkTests/ && mm) && adb install out/target/product/dream/system/app/FrameworkTest.apk"
336
337# runs all of FrameworkTests unit tests
338alias runtests="adb shell am instrument -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner"
339
340# runtest TEST: runs a single unit test, for instance runtest view.VisibilityTest
341# -- for convenience, you don't have to type the com.google.android.frameworktest.tests.
342function runtest {
343 adb shell am instrument -e class com.google.android.frameworktest.tests.$1 -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner
344}
345
346# debugtest TEST: runs a single unit test in debug mode, for instance runtest view.VisibilityTest
347function debugtest {
348 adb shell am instrument -e debug true -e class com.google.android.frameworktest.tests.$1 -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner
349}
350</pre>
351
352
353<p><span class="lh2"><a name="androidFooter"></a></span>
354
355 </div>
356 </div>
357 <!-- end gc-pagecontent -->
358 </div>
359 <!-- end gooey wrapper -->
360 </div>
361 <!-- end codesearchresults -->
362 <div id="gc-footer" dir="ltr">
363 <div class="text"> &copy;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>
364 </div>
365 <!-- end gc-footer -->
366</div>
367<!-- end gc-containter -->
368<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
369</script>
370<script type="text/javascript">
371 try {
372 var pageTracker = _gat._getTracker("UA-18071-1");
373 pageTracker._setAllowAnchor(true);
374 pageTracker._initData();
375 pageTracker._trackPageview();
376 } catch(e) {}
377</script>
378<div id="jd-build-id"> v0.3 - 9 June 2008</div>
379</div></div></div></body>
380</html>
381