1page.title=Activity Testing Tutorial
2parent.title=Testing
3parent.link=index.html
4@jd:body
5 <div id="qv-wrapper">
6  <div id="qv">
7  <h2>In this document</h2>
8  <ol>
9    <li>
10      <a href="#Prerequisites">Prerequisites</a>
11    </li>
12    <li>
13      <a href="#DownloadCode">Installing the Tutorial Sample Code</a>
14    </li>
15    <li>
16        <a href="#SetupEmulator">Setting Up the Emulator</a>
17    </li>
18    <li>
19        <a href="#SetupProjects">Setting Up the Projects</a>
20    </li>
21    <li>
22      <a href="#CreateTestCaseClass">Creating the Test Case Class</a>
23      <ol>
24        <li>
25          <a href="#AddTestCaseClass">Adding the test case class file</a>
26        </li>
27        <li>
28          <a href="#AddConstructor">Adding the test case constructor</a>
29        </li>
30        <li>
31            <a href="#AddSetupMethod">Adding the setup method</a>
32        </li>
33        <li>
34            <a href="#AddPreConditionsTest">Adding an initial conditions test</a>
35        </li>
36        <li>
37            <a href="#AddUITest">Adding a UI test</a>
38        </li>
39        <li>
40            <a href="#StateManagementTests">Adding state management tests</a>
41        </li>
42      </ol>
43    </li>
44    <li>
45        <a href="#RunTests">Running the Tests and Seeing the Results</a>
46    </li>
47    <li>
48        <a href="#TestFailure">Forcing Some Tests to Fail</a>
49    </li>
50    <li>
51        <a href="#NextSteps">Next Steps</a>
52    </li>
53</ol>
54<h2 id="#Appendix">Appendix</h2>
55<ol>
56    <li>
57        <a href="#InstallCompletedTestApp">Installing the Completed Test Application File</a>
58    </li>
59    <li>
60        <a href="#EditorCommandLine">For Users Not Developing In Eclipse</a>
61    </li>
62</ol>
63<h2>See Also</h2>
64<ol>
65    <li>
66        <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>
67    </li>
68    <li>
69        {@link android.test.ActivityInstrumentationTestCase2}
70    </li>
71    <li>
72        {@link junit.framework.Assert}
73    </li>
74    <li>
75        {@link android.test.InstrumentationTestRunner}
76    </li>
77</ol>
78</div>
79</div>
80<p>
81  Android includes powerful tools for testing applications. The tools extend JUnit with additional features, provide convenience classes for mock Android system objects, and use
82  instrumentation to give you control over your main application while you are testing it. The entire Android testing environment is discussed in the document
83  <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>.
84</p>
85<p>
86  This tutorial demonstrates the Android testing tools by presenting a simple Android application and then leading you step-by-step through the creation of a test application for it.
87  The test application demonstrates these key points:
88</p>
89  <ul>
90    <li>
91      An Android test is itself an Android application that is linked to the application under test by entries in its <code>AndroidManifest.xml</code> file.
92    </li>
93    <li>
94      Instead of Android components, an Android test application contains one or more test cases. Each of these is a separate class definition.
95    </li>
96    <li>
97      Android test case classes extend the JUnit {@link junit.framework.TestCase} class.
98    </li>
99    <li>
100      Android test case classes for activities extend JUnit and also connect you to the application under test with instrumentation. You can send keystroke or touch events directly to the UI.
101    </li>
102    <li>
103      You choose an Android test case class based on the type of component (application, activity, content provider, or service) you are testing.
104    </li>
105    <li>
106      Additional test tools in Eclipse/ADT provide integrated support for creating test applications, running them, and viewing the results.
107    </li>
108  </ul>
109<p>
110  The test application contains methods that perform the following tests:
111</p>
112  <ul>
113    <li>
114      Initial conditions test. Tests that the application under test initializes correctly. This is also a unit test of the application's
115      {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method. Testing initial conditions also provides a confidence measure for subsequent tests.
116    </li>
117    <li>
118      UI test. Tests that the main UI operation works correctly. This test demonstrates the instrumentation features available in activity testing.
119      It shows that you can automate UI tests by sending key events from the test application to the main application.
120    </li>
121    <li>
122      State management tests. Test the application's code for saving state. This test demonstrates the instrumentation features of the test runner, which
123      are available for testing any component.
124    </li>
125  </ul>
126<h2 id="Prerequisites">Prerequisites</h2>
127<p>
128  The instructions and code in this tutorial depend on the following:
129</p>
130  <ul>
131    <li>
132      Basic knowledge of Android programming. If you haven't yet written an Android application,
133      do the class
134      <a href="{@docRoot}training/basics/firstapp/index.html">Building Your First App</a>.
135      If you want to learn more about Spinner, the application under test, then you
136      might want to review the "Spinner" sample app.
137    </li>
138    <li>
139      Some familiarity with the Android testing framework and concepts. If you haven't explored
140      Android testing yet, start by reading the
141      <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>
142      guide.
143    </li>
144    <li>
145        Eclipse with ADT. This tutorial describes how to set up and run a test application using
146        Eclipse with ADT. If you haven't yet installed Eclipse and the ADT plugin,
147        follow the steps in <a href="{@docRoot}sdk/installing/index.html">Installing the SDK</a>
148        to install them before continuing. If you are not developing in Eclipse, you will
149        find instructions for setting up and running the test application in the
150        <a href="#EditorCommandLine">appendix</a> of this document.
151    </li>
152  </ul>
153<h2 id="DownloadCode">Installing the Tutorial Sample Code</h2>
154<p>
155    During this tutorial, you will be working with sample code that is provided as part
156    of the downloadable Samples component of the SDK. Specifically, you will be working
157    with a pair of related sample applications &mdash; an application under test and a test
158    application:
159</p>
160    <ul>
161        <li>
162            Spinner is the application under test. This tutorial focuses on the
163            common situation of writing tests for an application that already exists, so the main
164            application is provided to you.
165        </li>
166        <li>
167             SpinnerTest is the test application. In the tutorial, you create this application
168             step-by-step. If you want to run quickly through the tutorial,
169             you can install the completed SpinnerTest application first, and then follow the
170             text. You may get more from the tutorial, however, if you create the test application
171             as you go. The instructions for installing the completed test application are in the
172             section
173             <a href="#InstallCompletedTestApp">Installing the Completed Test Application File</a>.
174        </li>
175    </ul>
176<p>
177    The sample applications are described in more detail in the
178    <a href="{@docRoot}tools/samples/index.html">Samples</a> topic. Follow the instructions to
179    download the version of the samples that's appropriate for the platform you're working with.
180</p>
181<h2 id="SetupEmulator">Setting Up the Emulator</h2>
182<p>
183  In this tutorial, you will use the Android emulator to run applications. The emulator needs
184  an Android Virtual Device (AVD) with an API level equal to or higher than the one you set for the projects in the previous step.
185  To find out how to check this and create the right AVD if necessary,
186  see <a href="{@docRoot}tools/devices/managing-avds.html">Creating an AVD</a>.
187</p>
188<p>
189    As a test of the AVD and emulator, run the SpinnerActivity application in Eclipse with ADT. When it starts,
190    click the large downward-pointing arrow to the right of the spinner text. You see the spinner expand and display the title &quot;Select a planet&quot; at the top.
191    Click one of the other planets. The spinner closes, and your selection appears below it on the screen.
192</p>
193<h2 id="SetupProjects">Setting Up the Projects</h2>
194<p>
195    When you are ready to get started with the tutorial, begin by setting up Eclipse projects for
196    both Spinner (the application under test) and SpinnerTest (the test application).
197</p>
198<p>
199    You'll be using the Spinner application as-is, without modification, so you'll be loading it
200    into Eclipse as a new Android project from existing source. In the process, you'll be
201    creating a new test project associated with Spinner that will contain the SpinnerTest
202    application. The SpinnerTest application will be completely new and you'll be
203    using the code examples in this tutorial to add test classes and tests to it.
204</p>
205<p>
206    To install the Spinner app in a new Android project from existing source, following these steps:
207</p>
208<ol>
209    <li>
210        In Eclipse, select <strong>File</strong>&nbsp;&gt;&nbsp;<strong>New</strong>&nbsp;&gt;&nbsp;<strong>Project</strong>&nbsp;&gt;&nbsp;<strong>Android</strong>&nbsp;&gt;&nbsp;<strong>Android Project</strong>,
211        then click Next. The <strong>New Android Project</strong> dialog appears.
212    </li>
213    <li>
214        In the <em>Project name</em> text box, enter &quot;SpinnerActivity&quot;. The <em>Properties</em> area is filled in automatically.
215    </li>
216    <li>
217        In the <em>Contents</em> area, set &quot;Create project from existing source&quot;.
218    </li>
219    <li>
220        For <em>Location</em>, click <strong>Browse</strong>, navigate to the directory <code>&lt;SDK_path&gt;/samples/android-8/Spinner</code>,
221        then click Open. The directory name <code>&lt;SDK_path&gt;/samples/android-8/Spinner</code> now appears in the <em>Location</em> text box.
222    </li>
223    <li>
224        In the <em>Build Target</em> area, set a API level of 3 or higher. If you are already developing with a particular target, and it is API level 3 or higher, then use that target.
225    </li>
226    <li>
227        In the <em>Properties</em> area, in the <em>Min SDK Version:</em>, enter &quot;3&quot;.
228    </li>
229    <li>
230        You should now see these values:
231        <ul>
232            <li><em>Project Name:</em> &quot;SpinnerActivity&quot;</li>
233            <li><em>Create project from existing source:</em> set</li>
234            <li><em>Location:</em> &quot;<code>&lt;SDK_path&gt;/samples/android-8/Spinner</code>&quot;</li>
235            <li><em>Build Target:</em> &quot;API level of 3 or higher&quot; (<em>Target Name</em> &quot;Android 1.5 or higher&quot;)</li>
236            <li><em>Package name:</em> (disabled, set to &quot;<code>com.android.example.spinner</code>&quot;)</li>
237            <li><em>Create Activity:</em> (disabled, set to &quot;.SpinnerActivity&quot;)</li>
238            <li><em>Min SDK Version:</em> &quot;3&quot;</li>
239        </ul>
240        <p>
241            The following screenshot summarizes these values:
242        </p>
243            <a href="{@docRoot}images/testing/eclipse_new_android_project_complete_callouts.png">
244                <img src="{@docRoot}images/testing/eclipse_new_android_project_complete_callouts.png" alt="New Android Project dialog with filled-in values" style="height:230px"/>
245            </a>
246
247    </li>
248</ol>
249<p>
250    To create a new test project for the SpinnerTest application, follow these steps:
251</p>
252<ol>
253    <li>
254        Click Next. The <strong>New Android Test Project</strong> dialog appears.
255    </li>
256    <li>
257        Set &quot;Create a Test Project&quot;.
258    </li>
259    <li>
260        Leave the other values unchanged. The result should be:
261        <ul>
262            <li><em>Create a Test Project:</em> checked</li>
263            <li><em>Test Project Name:</em> &quot;SpinnerActivityTest&quot;</li>
264            <li><em>Use default location:</em> checked (this should contain the directory name &quot;<code>workspace/SpinnerActivityTest</code>&quot;).</li>
265            <li><em>Build Target:</em> Use the same API level you used in the previous step.</li>
266            <li><em>Application name:</em> &quot;SpinnerActivityTest&quot;</li>
267            <li><em>Package name:</em> &quot;<code>com.android.example.spinner.test</code>&quot;</li>
268            <li><em>Min SDK Version:</em> &quot;3&quot;</li>
269        </ul>
270        <p>
271            The following screenshot summarizes these values:
272        </p>
273            <a href="{@docRoot}images/testing/eclipse_new_android_testproject_complete_callouts.png">
274            <img src="{@docRoot}images/testing/eclipse_new_android_testproject_complete_callouts.png" alt="New Android Test Project dialog with filled-in values" style="height:230px"/>
275            </a>
276    </li>
277    <li>
278        Click Finish. Entries for SpinnerActivity and SpinnerActivityTest should appear in the
279        <strong>Package Explorer</strong>.
280        <p class="note">
281            <strong>Note:</strong> If you set <em>Build Target</em> to an API level higher than &quot;3&quot;, you will see the warning
282            &quot;The API level for the selected SDK target does not match the Min SDK version&quot;. You do not need to change the API level or the Min SDK version.
283            The message tells you that you are building the projects with one particular API level, but specifying that a lower API level is required. This may
284            occur if you have chosen not to install the optional earlier API levels.
285        </p>
286        <p>
287            If you see errors listed in the <strong>Problems</strong> pane at the bottom of the Eclipse window, or if a red error marker appears next to
288            the entry for SpinnerActivity in the Package Explorer, highlight the SpinnerActivity entry and then select
289            <strong>Project</strong>&nbsp;&gt;&nbsp;<strong>Clean</strong>. This should fix any errors.
290        </p>
291    </li>
292</ol>
293<p>
294    You now have the application under test in the SpinnerActivity project,
295    and an empty test project in SpinnerActivityTest. You may
296    notice that the two projects are in different directories, but Eclipse with
297    ADT handles this automatically. You should have no problem in either building or running them.
298</p>
299<p>
300    Notice that Eclipse and ADT have already done some initial setup for your test application.
301    Expand the SpinnerActivityTest project, and notice that it already has an
302    Android manifest file <code>AndroidManifest.xml</code>.
303    Eclipse with ADT created this when you added the test project.
304    Also, the test application is already set up to use instrumentation. You can see this
305    by examining <code>AndroidManifest.xml</code>.
306    Open it, then at the bottom of the center pane click <strong>AndroidManifest.xml</strong>
307    to display the XML contents:
308</p>
309<pre>
310&lt;?xml version="1.0" encoding="utf-8"?&gt;
311&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
312      package="com.android.example.spinner.test"
313      android:versionCode="1"
314      android:versionName="1.0"&gt;
315    &lt;uses-sdk android:minSdkVersion="3" /&gt;
316    &lt;instrumentation
317        android:targetPackage="com.android.example.spinner"
318        android:name="android.test.InstrumentationTestRunner" /&gt;
319    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
320        &lt;uses-library android:name="android.test.runner" /&gt;
321        ...
322    &lt;/application&gt;
323&lt;/manifest&gt;
324</pre>
325<p>
326    Notice the <code>&lt;instrumentation&gt;</code> element. The attribute
327    <code>android:targetPackage="com.android.example.spinner"</code> tells Android that the
328    application under test is defined in the Android package
329    <code>com.android.example.spinner</code>. Android now knows to use that
330    package's <code>AndroidManifest.xml</code> file to launch the application under test.
331    The <code>&lt;instrumentation&gt;</code> element also contains the attribute
332    <code>android:name="android.test.InstrumentationTestRunner"</code>, which tells Android
333    instrumentation to run the test application with Android's instrumentation-enabled test runner.
334</p>
335<h2 id="CreateTestCaseClass">Creating the Test Case Class</h2>
336
337<p>
338    You now have a test project SpinnerActivityTest, and the basic structure of a test
339    application also called SpinnerActivityTest. The basic structure includes all the files and
340    directories you need to build and run a test application, except for the class that
341    contains your tests (the test case class).
342</p>
343<p>
344    The next step is to define the test case class. In this tutorial, you'll be creating a
345    test case class that includes:
346</p>
347<ul>
348    <li>
349        Test setup. This use of the JUnit {@link junit.framework.TestCase#setUp() setUp()}
350        method demonstrates some of the tasks you might perform before running an Android test.
351    </li>
352    <li>
353        Testing initial conditions. This test demonstrates a good testing technique.
354        It also demonstrates that with Android instrumentation you can look at the application
355        under test <em>before</em> the main activity starts. The test checks that the application's
356        important objects have been initialized.
357        If the test fails, you then know that any other tests against the application are
358        unreliable, since the application was running in an incorrect state.
359        <p class="note">
360            <strong>Note:</strong> The purpose of testing initial conditions is not the same as
361            using <code>setUp()</code>. The JUnit {@link junit.framework.TestCase#setUp()} runs once
362            before <strong>each test method</strong>, and its purpose is to create a clean test
363            environment. The initial conditions test runs once, and its purpose is to verify that the
364            application under test is ready to be tested.
365        </p>
366    </li>
367    <li>
368        Testing the UI. This test shows how to control the main application's UI
369        with instrumentation, a powerful automation feature of Android testing.
370    </li>
371    <li>
372        Testing state management. This test shows some techniques for testing how
373        well the application maintains state in the Android environment. Remember that to
374        provide a satisfactory user experience, your application must never lose its current state,
375        even if it's interrupted by a phone call or destroyed because of memory constraints.
376        The Android activity lifecycle provides ways to maintain state, and the
377        <code>SpinnerActivity</code> application uses them. The test shows the techniques for
378        verifying that they work.
379    </li>
380</ul>
381<p>
382  Android tests are contained in a special type of Android application that contains one or more test class definitions. Each of these contains
383  one or more test methods that do the actual tests. In this tutorial, you will first add a test case class, and then add tests to it.
384</p>
385<p>
386 You first choose an Android test case class to extend. You choose from the base test case classes according to the Android component you are testing and the types of tests you are doing.
387 In this tutorial, the application under test has a single simple activity, so the test case class will be for an Activity component. Android offers several, but the one that tests in
388 the most realistic environment is {@link android.test.ActivityInstrumentationTestCase2}, so you will use it as the base class. Like all activity test case classes,
389 <code>ActivityInstrumentationTestCase2</code> offers convenience methods for interacting directly with the UI of the application under test.
390</p>
391<h3 id="AddTestCaseClass">Adding the test case class file</h3>
392<p>
393    To add <code>ActivityInstrumentationTestCase2</code> as the base test case class, follow these steps:
394</p>
395<ol>
396  <li>
397    In the Package Explorer, expand the test project SpinnerActivityTest if it is not open already.
398  </li>
399  <li>
400    Within SpinnerActivityTest, expand the <code>src/</code> folder and then the package marker for
401    <code>com.android.example.spinner.test</code>. Right-click on the package name and select <strong>New</strong> &gt; <strong>Class</strong>:<br/>
402    <a href="{@docRoot}images/testing/spinner_create_test_class_callouts.png">
403      <img alt="Menu for creating a new class in the test application" src="{@docRoot}images/testing/spinner_create_test_class_callouts.png" style="height:230px"/>
404    </a>
405    <p>
406      The <strong>New Java Class</strong> wizard appears:
407    </p>
408    <a href="{@docRoot}images/testing/spinnertest_new_class_callouts.png">
409      <img alt="New Java Class wizard dialog" src="{@docRoot}images/testing/spinnertest_new_class_callouts.png" style="height:230px"/>
410    </a>
411  </li>
412  <li>
413    In the wizard, enter the following:
414    <ul>
415      <li>
416        <em>Name:</em> &quot;SpinnerActivityTest&quot;. This becomes the name of your test class.
417      </li>
418      <li>
419        <em>Superclass:</em> &quot;<code>android.test.ActivityInstrumentationTestCase2&lt;SpinnerActivity&gt;</code>&quot;. The superclass is parameterized, so
420        you have to provide it your main application's class name.
421      </li>
422    </ul>
423    <p>
424      Do not change any of the other settings. Click Finish.
425    </p>
426  </li>
427  <li>
428    You now have a new file <code>SpinnerActivityTest.java</code> in the project.
429  </li>
430  <li>
431    To resolve the reference to SpinnerActivity, add the following import:
432<pre>
433import com.android.example.spinner.SpinnerActivity;
434</pre>
435  </li>
436</ol>
437<h3 id="AddConstructor">Adding the test case constructor</h3>
438  <p>
439    To ensure that the test application is instantiated correctly, you must set up a constructor that the test
440    runner will call when it instantiates your test class. This constructor has no parameters, and its sole
441    purpose is to pass information to the superclass's default constructor. To set up this constructor, enter the
442    following code in the class:
443  </p>
444<pre>
445  public SpinnerActivityTest() {
446    super(SpinnerActivity.class);
447  } // end of SpinnerActivityTest constructor definition
448</pre>
449<p>
450  This calls the superclass constructor with the main activity's class (<code>SpinnerActivity.class</code>) for the application under test. Android uses this information to find the application and activity to test.
451</p>
452<p>
453  You are now ready to add tests, by adding test methods to the class.
454</p>
455<h3 id="AddSetupMethod">Adding the setup method</h3>
456<p>
457    The <code>setUp()</code> method is invoked before every test. You use it to initialize variables and clean up from previous tests. You can also use
458    the JUnit {@link junit.framework.TestCase#tearDown() tearDown()} method, which runs <strong>after</strong> every test method. The tutorial does not use it.
459</p>
460<p>
461    The method you are going to add does the following:
462</p>
463<ul>
464  <li>
465    <code>super.setUp()</code>. Invokes the superclass constructor for <code>setUp()</code>, which is required by JUnit.
466  </li>
467  <li>
468    Calls {@link android.test.ActivityInstrumentationTestCase2#setActivityInitialTouchMode(boolean) setActivityInitialTouchMode(false)}.
469    This turns off <strong>touch mode</strong> in the device or emulator. If any of your test methods send key events to the application,
470    you must turn off touch mode <em>before</em> you start any activities; otherwise, the call is ignored.
471  </li>
472  <li>
473    Stores references to system objects. Retrieves and stores a reference to the activity under test, the <code>Spinner</code>
474    widget used by the activity, the <code>SpinnerAdapter</code> that backs the widget, and the string value of the selection that is
475    set when the application is first installed. These objects are used in the state management test. The methods invoked are:
476    <ul>
477      <li>
478        {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. Gets a reference to the activity under test (<code>SpinnerActivity</code>).
479        This call also starts the activity if it is not already running.
480      </li>
481      <li>
482        {@link android.app.Activity#findViewById(int)}. Gets a reference to the <code>Spinner</code> widget of the application under test.
483      </li>
484      <li>
485        {@link android.widget.AbsSpinner#getAdapter()}. Gets a reference to the adapter (an array of strings) backing the spinner.
486      </li>
487    </ul>
488  </li>
489</ul>
490<p>
491    Add this code to the definition of <code>SpinnerActivityTest</code>, after the constructor definition:
492</p>
493<pre>
494  &#64;Override
495  protected void setUp() throws Exception {
496    super.setUp();
497
498    setActivityInitialTouchMode(false);
499
500    mActivity = getActivity();
501
502    mSpinner =
503      (Spinner) mActivity.findViewById(
504        com.android.example.spinner.R.id.Spinner01
505      );
506
507      mPlanetData = mSpinner.getAdapter();
508
509  } // end of setUp() method definition
510</pre>
511<p>
512    Add these members to the test case class:
513</p>
514<pre>
515  private SpinnerActivity mActivity;
516  private Spinner mSpinner;
517  private SpinnerAdapter mPlanetData;
518</pre>
519<p>
520  Add these imports:
521</p>
522<pre>
523import android.widget.Spinner;
524import android.widget.SpinnerAdapter;
525</pre>
526<p>
527    You now have the complete <code>setUp()</code> method.
528</p>
529<h3 id="AddPreConditionsTest">Adding an initial conditions test</h3>
530<p>
531  The initial conditions test verifies that the application under test is initialized correctly. It is an illustration of the types of tests you can run, so it is not comprehensive.
532  It verifies the following:
533</p>
534<ul>
535  <li>
536    The item select listener is initialized. This listener is called when a selection is made from the spinner.
537  </li>
538  <li>
539    The adapter that provides values to the spinner is initialized.
540  </li>
541  <li>
542    The adapter contains the right number of entries.
543  </li>
544</ul>
545<p>
546  The actual initialization of the application under test is done in <code>setUp()</code>, which the test runner calls automatically before every test. The verifications are
547  done with JUnit {@link junit.framework.Assert} calls. As a useful convention, the method name is <code>testPreConditions()</code>:
548</p>
549<pre>
550  public void testPreConditions() {
551    assertTrue(mSpinner.getOnItemSelectedListener() != null);
552    assertTrue(mPlanetData != null);
553    assertEquals(mPlanetData.getCount(),ADAPTER_COUNT);
554  } // end of testPreConditions() method definition
555</pre>
556<p>
557  Add this member:
558</p>
559<pre>
560  public static final int ADAPTER_COUNT = 9;
561</pre>
562<h3 id="AddUITest">Adding a UI test</h3>
563<p>
564  Now create a UI test that selects an item from the <code>Spinner</code> widget. The test sends key events to the UI with key events.
565  The test confirms that the selection matches the result you expect.
566</p>
567<p>
568  This test demonstrates the power of using instrumentation in Android testing. Only an instrumentation-based test class allows you to send key events (or touch events)
569  to the application under test. With instrumentation, you can test your UI without having to take screenshots, record the screen, or do human-controlled testing.
570</p>
571<p>
572  To work with the spinner, the test has to request focus for it and then set it to a known position. The test uses {@link android.view.View#requestFocus() requestFocus()} and
573  {@link android.widget.AbsSpinner#setSelection(int) setSelection()} to do this. Both of these methods interact with a View in the application under test, so you have to call them
574  in a special way.
575</p>
576<p>
577  Code in a test application that interacts with a View of the application under test must run in the main application's thread, also
578  known as the <em>UI thread</em>. To do this, you use the {@link android.app.Activity#runOnUiThread(java.lang.Runnable) Activity.runOnUiThread()}
579  method. You pass the code to <code>runOnUiThread()</code>in an anonymous {@link java.lang.Runnable Runnable} object. To set
580  the statements in the <code>Runnable</code> object, you override the object's {@link java.lang.Runnable#run()} method.
581</p>
582<p>
583  To send key events to the UI of the application under test, you use the <a href="{@docRoot}reference/android/test/InstrumentationTestCase.html#sendKeys(int...)">sendKeys</a>() method.
584  This method does not have to run on the UI thread, since Android uses instrumentation to pass the key events to the application under test.
585</p>
586<p>
587  The last part of the test compares the selection made by sending the key events to a pre-determined value. This tests that the spinner is working as intended.
588</p>
589<p>
590    The following sections show you how to add the code for this test.
591</p>
592<ol>
593    <li>
594        Get focus and set selection. Create a new method <code>public void testSpinnerUI()</code>. Add
595        code to to request focus for the spinner and set its position to default or initial position, "Earth". This code is run on the UI thread of
596        the application under test:
597<pre>
598  public void testSpinnerUI() {
599
600    mActivity.runOnUiThread(
601      new Runnable() {
602        public void run() {
603          mSpinner.requestFocus();
604          mSpinner.setSelection(INITIAL_POSITION);
605        } // end of run() method definition
606      } // end of anonymous Runnable object instantiation
607    ); // end of invocation of runOnUiThread
608</pre>
609        <p>
610          Add the following member to the test case class.
611        </p>
612<pre>
613  public static final int INITIAL_POSITION = 0;
614</pre>
615    </li>
616    <li>
617      Make a selection. Send key events to the spinner to select one of the items. To do this, open the spinner by
618      "clicking" the center keypad button (sending a DPAD_CENTER key event) and then clicking (sending) the down arrow keypad button five times. Finally,
619      click the center keypad button again to highlight the desired item. Add the following code:
620<pre>
621    this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
622    for (int i = 1; i &lt;= TEST_POSITION; i++) {
623      this.sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
624    } // end of for loop
625
626    this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
627</pre>
628    <p>
629      Add the following member to the test case class:
630    </p>
631<pre>
632  public static final int TEST_POSITION = 5;
633</pre>
634    <p>
635      This sets the final position of the spinner to "Saturn" (the spinner's backing adapter is 0-based).
636    </p>
637  </li>
638  <li>
639    Check the result. Query the current state of the spinner, and compare its current selection to the expected value.
640    Call the method {@link android.widget.AdapterView#getSelectedItemPosition() getSelectedItemPosition()} to find out the current selection position, and then
641    {@link android.widget.AdapterView#getItemAtPosition(int) getItemAtPosition()} to get the object corresponding to that position (casting it to a String). Assert that
642    this string value matches the expected value of "Saturn":
643<pre>
644    mPos = mSpinner.getSelectedItemPosition();
645    mSelection = (String)mSpinner.getItemAtPosition(mPos);
646    TextView resultView =
647      (TextView) mActivity.findViewById(
648        com.android.example.spinner.R.id.SpinnerResult
649      );
650
651    String resultText = (String) resultView.getText();
652
653    assertEquals(resultText,mSelection);
654
655  } // end of testSpinnerUI() method definition
656</pre>
657<p>
658  Add the following members to the test case class:
659</p>
660<pre>
661  private String mSelection;
662  private int mPos;
663</pre>
664  <p>
665    Add the following imports to the test case class:
666  </p>
667<pre>
668  import android.view.KeyEvent;
669  import android.widget.TextView;
670</pre>
671  </li>
672</ol>
673<p>
674  Pause here to run the tests you have. The procedure for running a test application is different
675  from running a regular Android application. You run a test application as an Android JUnit
676  application. To see how to do this, see <a href="#RunTests">Running the Tests and Seeing the Results</a>.
677</p>
678<p>
679    Eventually, you will see the <code>SpinnerActivity</code> application start, and the test
680    application controlling it by sending it key events. You will also see a new
681    <strong>JUnit</strong> view in the Explorer pane, showing the results of the
682    test. The JUnit view is documented in a following section,
683    <a href="#RunTests">Running the Test and Seeing the Results</a>.
684</p>
685<h3 id="StateManagementTests">Adding state management tests</h3>
686<p>
687  You now write two tests that verify that SpinnerActivity maintains its state when it is paused or terminated.
688  The state, in this case, is the current selection in the spinner. When users make a selection,
689  pause or terminate the application, and then resume or restart it, they should see
690  the same selection.
691</p>
692<p>
693  Maintaining state is an important feature of an application. Users may switch from the current
694  application temporarily to answer the phone, and then switch back. Android may decide to
695  terminate and restart an activity to change the screen orientation, or terminate an unused
696  activity to regain storage. In each case, users are best served by having the UI return to its
697  previous state (except where the logic of the application dictates otherwise).
698</p>
699<p>
700  SpinnerActivity manages its state in these ways:
701</p>
702  <ul>
703    <li>
704      Activity is hidden. When the spinner screen (the activity) is running but hidden by some other screen, it
705      stores the spinner's position and value in a form that persists while the application is running.
706    </li>
707    <li>
708      Application is terminated. When the activity is terminated, it stores the spinner's position and value in
709      a permanent form. The activity can read the position and value when it restarts, and restore the spinner to its previous state.
710    </li>
711    <li>
712      Activity re-appears. When the user returns to the spinner screen, the previous selection is restored.
713    </li>
714    <li>
715      Application is restarted. When the user starts the application again, the previous selection is restored.
716    </li>
717  </ul>
718<p class="note">
719    <strong>Note:</strong> An application can manage its state in other ways as well, but these are
720    not covered in this tutorial.
721</p>
722<p>
723  When an activity is hidden, it is <strong>paused</strong>. When it re-appears, it
724  <strong>resumes</strong>. Recognizing that these are key points in an activity's life cycle,
725  the Activity class provides two callback methods {@link android.app.Activity#onPause()} and
726  {@link android.app.Activity#onResume()} for handling pauses and resumes.
727  SpinnerActivity uses them for code that saves and restores state.
728</p>
729<p>
730  <strong>Note:</strong> If you would like to learn more about the difference between losing
731  focus/pausing and killing an application,
732  read about the <a href="{@docRoot}guide/components/activities.html#Lifecycle">activity
733lifecycle</a>.
734</p>
735<p>
736  The first test verifies that the spinner selection is maintained after the entire application is shut down and then restarted. The test uses instrumentation to
737  set the spinner's variables outside of the UI. It then terminates the activity by calling {@link android.app.Activity#finish() Activity.finish()}, and restarts it
738  using the instrumentation method {@link android.test.ActivityInstrumentationTestCase2#getActivity()}. The test then asserts that the current spinner state matches
739  the test values.
740</p>
741<p>
742  The second test verifies that the spinner selection is maintained after the activity is paused and then resumed. The test uses instrumentation to
743  set the spinner's variables outside of the UI and then force calls to the <code>onPause()</code> and <code>onResume()</code> methods. The test then
744  asserts that the current spinner state matches the test values.
745</p>
746<p>
747  Notice that these tests make limited assumptions about the mechanism by which the activity manages state. The tests use the activity's getters and
748  setters to control the spinner. The first test also knows that hiding an activity calls <code>onPause()</code>, and bringing it back to the foreground
749  calls <code>onResume()</code>. Other than this, the tests treat the activity as a "black box".
750</p>
751<p>
752    To add the code for testing state management across shutdown and restart, follow these steps:
753</p>
754 <ol>
755    <li>
756      Add the test method <code>testStateDestroy()</code>, then
757      set the spinner selection to a test value:
758<pre>
759  public void testStateDestroy() {
760    mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);
761    mActivity.setSpinnerSelection(TEST_STATE_DESTROY_SELECTION);
762</pre>
763    </li>
764    <li>
765      Terminate the activity and restart it:
766<pre>
767    mActivity.finish();
768    mActivity = this.getActivity();
769</pre>
770    </li>
771    <li>
772      Get the current spinner settings from the activity:
773<pre>
774    int currentPosition = mActivity.getSpinnerPosition();
775    String currentSelection = mActivity.getSpinnerSelection();
776</pre>
777    </li>
778    <li>
779      Test the current settings against the test values:
780<pre>
781    assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
782    assertEquals(TEST_STATE_DESTROY_SELECTION, currentSelection);
783  } // end of testStateDestroy() method definition
784</pre>
785<p>
786  Add the following members to the test case class:
787<pre>
788  public static final int TEST_STATE_DESTROY_POSITION = 2;
789  public static final String TEST_STATE_DESTROY_SELECTION = "Earth";
790</pre>
791    </li>
792 </ol>
793<p>
794    To add the code for testing state management across a pause and resume, follow these steps:
795</p>
796<ol>
797    <li>
798      Add the test method <code>testStatePause()</code>:
799<pre>
800    &#64;UiThreadTest
801    public void testStatePause() {
802</pre>
803    <p>
804      The <code>@UiThreadTest</code> annotation tells Android to build this method so that it runs
805      on the UI thread. This allows the method to change the state of the spinner widget in the
806      application under test. This use of <code>@UiThreadTest</code> shows that, if necessary, you
807      can run an entire method on the UI thread.
808    </p>
809    </li>
810   <li>
811    Set up instrumentation. Get the instrumentation object
812    that is controlling the application under test. This is used later to
813    invoke the <code>onPause()</code> and <code>onResume()</code> methods:
814<pre>
815    Instrumentation mInstr = this.getInstrumentation();
816</pre>
817  </li>
818  <li>
819    Set the spinner selection to a test value:
820<pre>
821    mActivity.setSpinnerPosition(TEST_STATE_PAUSE_POSITION);
822    mActivity.setSpinnerSelection(TEST_STATE_PAUSE_SELECTION);
823</pre>
824  </li>
825  <li>
826    Use instrumentation to call the Activity's <code>onPause()</code>:
827<pre>
828    mInstr.callActivityOnPause(mActivity);
829</pre>
830    <p>
831      Under test, the activity is waiting for input. The invocation of
832      {@link android.app.Instrumentation#callActivityOnPause(android.app.Activity)}
833      performs a call directly to the activity's <code>onPause()</code> instead
834      of manipulating the activity's UI to force it into a paused state.
835    </p>
836  </li>
837  <li>
838    Force the spinner to a different selection:
839<pre>
840    mActivity.setSpinnerPosition(0);
841    mActivity.setSpinnerSelection("");
842</pre>
843    <p>
844      This ensures that resuming the activity actually restores the
845      spinner's state rather than simply leaving it as it was.
846    </p>
847  </li>
848  <li>
849    Use instrumentation to call the Activity's <code>onResume()</code>:
850<pre>
851    mInstr.callActivityOnResume(mActivity);
852</pre>
853    <p>
854      Invoking {@link android.app.Instrumentation#callActivityOnResume(android.app.Activity)}
855      affects the activity in a way similar to <code>callActivityOnPause</code>. The
856      activity's <code>onResume()</code> method is invoked instead of manipulating the
857      activity's UI to force it to resume.
858    </p>
859  </li>
860  <li>
861    Get the current state of the spinner:
862<pre>
863    int currentPosition = mActivity.getSpinnerPosition();
864    String currentSelection = mActivity.getSpinnerSelection();
865</pre>
866  </li>
867  <li>
868    Test the current spinner state against the test values:
869<pre>
870    assertEquals(TEST_STATE_PAUSE_POSITION,currentPosition);
871    assertEquals(TEST_STATE_PAUSE_SELECTION,currentSelection);
872  } // end of testStatePause() method definition
873</pre>
874    <p>
875      Add the following members to the test case class:
876    </p>
877<pre>
878  public static final int TEST_STATE_PAUSE_POSITION = 4;
879  public static final String TEST_STATE_PAUSE_SELECTION = "Jupiter";
880</pre>
881  </li>
882  <li>
883    Add the following imports:
884<pre>
885  import android.app.Instrumentation;
886  import android.test.UiThreadTest;
887</pre>
888  </li>
889</ol>
890<h2 id="RunTests">Running the Tests and Seeing the Results</h2>
891 <p>
892    The most simple way to run the <code>SpinnerActivityTest</code> test case is to run it directly from the Package Explorer.
893 </p>
894 <p>
895    To run the <code>SpinnerActivityTest</code> test, follow these steps:
896</p>
897 <ol>
898    <li>
899      In the Package Explorer, right-click the project SpinnerActivityTest at the top level, and then
900      select <strong>Run As</strong> &gt; <strong>Android JUnit Test</strong>:<br/>
901      <a href="{@docRoot}images/testing/spinnertest_runas_menu_callouts.png">
902        <img alt="Menu to run a test as an Android JUnit test" src="{@docRoot}images/testing/spinnertest_runas_menu_callouts.png" style="height:230px">
903      </a>
904    </li>
905    <li>
906        You will see the emulator start. When the unlock option is displayed (its appearance depends on the API level you specified for the AVD),
907        unlock the home screen.
908    </li>
909    <li>
910      The test application starts. You see a new tab for the <strong>JUnit</strong> view, next to the Package Explorer tab:<br/>
911      <a href="{@docRoot}images/testing/spinnertest_junit_panel.png">
912        <img alt="The JUnit window" src="{@docRoot}images/testing/spinnertest_junit_panel.png" style="height:230px">
913      </a>
914    </li>
915</ol>
916<p>
917    This view contains two sub-panes. The top pane summarizes the tests that were run, and the bottom pane shows failure traces for
918    highlighted tests.
919</p>
920<p>
921   At the conclusion of a successful test run, this is the view's appearance:<br/>
922   <a href="{@docRoot}images/testing/spinnertest_junit_success.png">
923    <img src="{@docRoot}images/testing/spinnertest_junit_success.png" alt="JUnit test run success" style="height:230px"/>
924   </a>
925</p>
926<p>
927    The upper pane summarizes the test:
928</p>
929    <ul>
930        <li>
931            Total time elapsed for the test application(labeled <em>Finished after &lt;x&gt; seconds</em>).
932        </li>
933        <li>
934            Number of runs (<em>Runs:</em>) - the number of tests in the entire test class.
935        </li>
936        <li>
937            Number of errors (<em>Errors:</em>) - the number of program errors and exceptions encountered during
938            the test run.
939        </li>
940        <li>
941            Number of failures (<em>Failures:</em>) - the number of test failures encountered during the test
942            run. This is the number of assertion failures. A test can fail even if the program does not encounter an error.
943        </li>
944        <li>
945            A progress bar. The progress bar extends from left to right as the tests run.
946            <p>
947               If all the tests succeed, the bar remains green. If a test fails, the bar turns from green to red.
948            </p>
949        </li>
950        <li>
951            A test method summary. Below the bar, you see a line for each class in the test application. To look at the results for the individual
952            methods in a test, click the arrow at the left to expand the line. You see the name of each test method. To the
953            right of the name, you see the time taken by the test. You can look at the test's code
954            by double-clicking its name.
955        </li>
956    </ul>
957<p>
958    The lower pane contains the failure trace. If all the tests are successful, this pane is empty. If some tests fail,
959    then if you highlight a failed test in the upper pane, the lower view contains a stack trace for the test. This is
960    demonstrated in the next section.
961</p>
962<p class="note">
963    <strong>Note:</strong> If you run the test application and nothing seems to happen, look for
964    the JUnit view. If you do not see it, you may have run the test application
965    as a regular Android application.
966    Remember that you need to run it as an Android <strong>JUnit</strong>
967    application.
968</p>
969<h2 id="TestFailure">Forcing Some Tests to Fail</h2>
970<p>
971  A test is as useful when it fails as when it succeeds. This section shows what happens in Eclipse with ADT when a test fails. You
972  can quickly see that a test class has failed, find the method or methods that failed, and then use a failure trace to find
973  the exact problem.
974</p>
975<p>
976  The example application SpinnerActivity that you downloaded passes all the tests in the test application SpinnerActivityTest.
977  To force the test to fail, you must modify the example application. You change a line of setup code in the application under test. This
978  causes the <code>testPreConditions()</code> and <code>testTextView()</code> test methods to fail.
979</p>
980<p>
981    To force the tests to fail, follow these steps:
982</p>
983<ol>
984  <li>
985    In Eclipse with ADT, go to the SpinnerActivity project and open the file <code>SpinnerActivity.java</code>.
986  </li>
987  <li>
988    At the top of <code>SpinnerActivity.java</code>, at the end of the <code>onCreate()</code> method, find the following line:
989<pre>
990    // mySpinner.setOnItemSelectedListener(null);
991</pre>
992    <p>Remove the forward slash characters at the beginning of the line to
993    uncomment the line. This sets the listener callback to null:
994    </p>
995<pre>
996    mySpinner.setOnItemSelectedListener(null);
997</pre>
998  </li>
999  <li>
1000    The <code>testPreConditions()</code> method in <code>SpinnerActivityTest</code> contains the following test:
1001    <code>assertTrue(mSpinner.getOnItemSelectedListener() != null);</code>. This test asserts that the listener callback is <em>not</em> null.
1002    Since you have modified the application under test, this assertion now fails.
1003  </li>
1004  <li>
1005    Run the test, as described in the previous section <a href="#RunTests">Running the Tests and Seeing the Results</a>.
1006  </li>
1007</ol>
1008<p>
1009    The JUnit view is either created or updated with the results of the test. Now, however, the progress bar is red,
1010    the number of failures is 2, and small "x" icons appear in the list icons next to the testPreConditions and
1011    TestSpinnerUI tests. This indicates that the tests have failed. The display is similar to this:<br/>
1012    <a href="{@docRoot}images/testing/spinnertest_junit_panel_fail_callouts.png">
1013      <img src="{@docRoot}images/testing/spinnertest_junit_panel_fail_callouts.png" alt="The JUnit Failure window" style="height:230px"/>
1014    </a>
1015</p>
1016<p>
1017  You now want to look at the failures to see exactly where they occurred.
1018</p>
1019<p>
1020    To examine the failures, follow these steps:
1021</p>
1022<ol>
1023  <li>
1024    Click the testPreconditions entry. In the lower pane entitled <strong>Failure Trace</strong>,
1025    you see a stack trace of the calls that led to the failure. This trace is similar to the following screenshot:<br/>
1026    <a href="{@docRoot}images/testing/spinnertest_junit_panel_failtrace_callouts.png">
1027      <img src="{@docRoot}images/testing/spinnertest_junit_panel_failtrace_callouts.png" alt="The JUnit failure trace" style="height:230px"/>
1028    </a>
1029  </li>
1030  <li>
1031      The first line of the trace tells you the error. In this case, a JUnit assertion failed. To look at the
1032      assertion in the test code, double-click the next line (the first line of the trace). In the center pane
1033      a new tabbed window opens, containing the code for the test application <code>SpinnerActivityTest</code>. The failed assertion
1034      is highlighted in the middle of the window.
1035  </li>
1036</ol>
1037<p>
1038    The assertion failed because you modified the main application to set the <code>getOnItemSelectedListener</code> callback to <code>null</code>.
1039</p>
1040<p>
1041    You can look at the failure in <code>testTextView</code> if you want. Remember, though, that <code>testPreConditions</code> is meant to verify the
1042    initial setup of the application under test. If testPreConditions() fails, then succeeding tests can't be trusted. The best strategy to follow is to
1043    fix the problem and re-run all the tests.
1044</p>
1045<p>
1046    Remember to go back to <code>SpinnerActivity.java</code> and re-comment the line you uncommented in an earlier step.
1047</p>
1048<p>
1049  You have now completed the tutorial.
1050</p>
1051<h2 id="NextSteps">Next Steps</h2>
1052<p>
1053    This example test application has shown you how to create a test project and link it to
1054    the application you want to test, how to choose and add a test case class, how to write
1055    UI and state management tests, and how to run the tests against the application under
1056    test. Now that you are familiar with the basics of testing Android applications, here
1057    are some suggested next steps:
1058</p>
1059<p>
1060    <strong>Learn more about testing on Android</strong>
1061</p>
1062<ul>
1063    <li>
1064        If you haven't done so already, read the
1065        <a href="{@docRoot}tools/testing/testing_android.html">Testing Fundamentals</a>
1066        document in the <em>Dev Guide</em>. It provides an overview of how testing on Android
1067        works. If you are just getting started with Android testing, reading that document will
1068        help you understand the tools available to you, so that you can develop effective
1069        tests.
1070    </li>
1071</ul>
1072<p>
1073    <strong>Review the main Android test case classes</strong>
1074</p>
1075<ul>
1076    <li>
1077        {@link android.test.ActivityInstrumentationTestCase2}
1078    </li>
1079    <li>
1080        {@link android.test.ActivityUnitTestCase}
1081    </li>
1082    <li>
1083        {@link android.test.ProviderTestCase2}
1084    </li>
1085    <li>
1086        {@link android.test.ServiceTestCase}
1087    </li>
1088</ul>
1089<p>
1090    <strong>Learn more about the assert and utility classes</strong>
1091</p>
1092<ul>
1093    <li>
1094        {@link junit.framework.Assert}, the JUnit Assert class.
1095    </li>
1096    <li>
1097        {@link android.test.MoreAsserts}, additional Android assert methods.
1098    </li>
1099    <li>
1100        {@link android.test.ViewAsserts}, useful assertion methods for testing Views.
1101    </li>
1102    <li>
1103        {@link android.test.TouchUtils}, utility methods for simulating touch events in an Activity.
1104    </li>
1105</ul>
1106<p>
1107    <strong>Learn about instrumentation and the instrumented test runner</strong>
1108</p>
1109<ul>
1110    <li>
1111        {@link android.app.Instrumentation}, the base instrumentation class.
1112    </li>
1113    <li>
1114        {@link android.test.InstrumentationTestCase}, the base instrumentation test case.
1115    </li>
1116    <li>
1117        {@link android.test.InstrumentationTestRunner}, the standard Android test runner.
1118    </li>
1119</ul>
1120<h2 id="Appendix">Appendix</h2>
1121<h3 id="InstallCompletedTestApp">Installing the Completed Test Application File</h3>
1122<p>
1123    The recommended approach to this tutorial is to follow the instructions step-by-step and
1124    write the test code as you go. However, if you want to do this tutorial quickly,
1125    you can install the entire file for the test application into the test project.
1126</p>
1127<p>
1128    To do this, you first create a test project with the necessary structure and files by using
1129    the automated tools in Eclipse. Then you exit Eclipse and copy the test application's file
1130    from the SpinnerTest sample project into your test project. The SpinnerTest sample project is
1131    part of the Samples component of the SDK.
1132</p>
1133<p>
1134    The result is a complete test application, ready to run against the Spinner sample application.
1135</p>
1136<p>
1137    To install the test application file, follow these steps:
1138</p>
1139<ol>
1140    <li>
1141        Set up the projects for the application under test and the test application, as described
1142        in the section section <a href="#SetupProjects">Setting Up the Projects</a>.
1143    </li>
1144    <li>
1145        Set up the emulator, as described in the section <a href="#SetupEmulator">Setting Up the Emulator</a>.
1146    </li>
1147    <li>
1148        Add the test case class, as described in the section <a href="#AddTestCaseClass">Adding the test case class file</a>.
1149    </li>
1150    <li>
1151        Close Eclipse with ADT.
1152    </li>
1153    <li>
1154        Copy the file <code>&lt;SDK_path&gt;/samples/android-8/SpinnerTest/src/com/android/example/spinner/test/SpinnerActivityTest.java</code>
1155        to the directory <code>workspace/SpinnerActivityTest/src/com/android/example/spinner/test/</code>.
1156    </li>
1157    <li>
1158        Restart Eclipse with ADT.
1159    </li>
1160    <li>
1161        In Eclipse with ADT, re-build the project <code>SpinnerActivityTest</code> by selecting it in the Package Explorer, right-clicking,
1162        and selecting <em>Project</em>&nbsp;&gt;&nbsp;<em>Clean</em>.
1163    </li>
1164    <li>
1165        The complete, working test application should now be in the <code>SpinnerActivityTest</code> project.
1166    </li>
1167</ol>
1168<p>
1169    You can now continue with the tutorial, starting at the section <a href="#AddConstructor">Adding the test case constructor</a> and
1170    following along in the text.
1171</p>
1172<h3 id="EditorCommandLine">For Users Not Developing In Eclipse</h3>
1173<p>
1174    If you are not developing in Eclipse, you can still do this tutorial. Android provides tools for
1175    creating test applications using a code editor and command-line tools. You use the following tools:
1176</p>
1177<ul>
1178  <li>
1179   <a href="{@docRoot}tools/help/adb.html">adb</a> - Installs and uninstalls applications and test applications to a device or the emulator. You
1180   also use this tool to run the test application from the command line.
1181  </li>
1182  <li>
1183    <a href="{@docRoot}tools/help/android.html">android</a> - Manages projects and test projects. This tool also manages AVDs and Android platforms.
1184  </li>
1185</ul>
1186  <p>
1187    You use the <code>emulator</code> tool to run the emulator from the command line.
1188  </p>
1189  <p>
1190    Here are the general steps for doing this tutorial using an editor and the command line:
1191  </p>
1192<ol>
1193  <li>
1194    As described in the section <a href="#DownloadCode">Installing the Tutorial Sample Code</a>, get the sample code. You will then
1195    have a directory <code>&lt;SDK_path&gt;/samples/android-8</code>, containing (among others) the directories <code>Spinner</code>
1196    and <code>SpinnerTest</code>:
1197    <ul>
1198        <li>
1199            <code>Spinner</code> contains the main application, also known as the <strong>application under test</strong>. This tutorial focuses on the
1200            common situation of writing tests for an application that already exists, so the main application is provided to you.
1201        </li>
1202        <li>
1203            <code>SpinnerTest</code> contains all the code for the test application. If you want to run quickly through the tutorial, you can
1204            install the test code and then follow the text. You may get more from the tutorial, however, if you write the code as you go. The instructions
1205            for installing the test code are in the section <a href="#InstallCompletedTestApp">Appendix: Installing the Completed Test Application File</a>.
1206        </li>
1207        </ul>
1208  </li>
1209  <li>
1210    Navigate to the directory <code>&lt;SDK_path&gt;/samples/android-8</code>.
1211  </li>
1212  <li>
1213    Create a new Android application project using <code>android create project</code>:
1214<pre>
1215$ android create project -t &lt;APItarget&gt; -k com.android.example.spinner -a SpinnerActivity -n SpinnerActivity -p Spinner
1216</pre>
1217    <p>
1218        The value of <code>&lt;APItarget&gt;</code> should be &quot;3&quot; (API level 3) or higher. If you are already developing with a particular API level, and it is
1219        higher than 3, then use that API level.
1220    </p>
1221    <p>
1222        This a new Android project <code>SpinnerActivity</code> in the existing <code>Spinner</code> directory. The existing source and
1223        resource files are not touched, but the <code>android</code> tool adds the necessary build files.
1224    </p>
1225  </li>
1226  <li>
1227    Create a new Android test project using <code>android create test-project</code>:
1228<pre>
1229$ android create test-project -m ../Spinner -n SpinnerActivityTest -p SpinnerActivityTest
1230</pre>
1231    <p>
1232        This will create a new Android test project in the <em>new</em> directory <code>SpinnerActivityTest</code>. You do this
1233        so that the solution to the tutorial that is in <code>SpinnerTest</code> is left untouched. If you want to use the solution
1234        code instead of entering it as you read through the tutorial, refer to the section
1235        <a href="#InstallCompletedTestApp">Appendix: Installing the Completed Test Application File</a>.
1236    </p>
1237    <p class="Note">
1238      <strong>Note:</strong> Running <code>android create test-project</code> will automatically create
1239      the file <code>AndroidManifest.xml</code> with the correct <code>&lt;instrumentation&gt;</code> element.
1240    </p>
1241  </li>
1242  <li>
1243    Build the sample application. If you are building with Ant, then it is easiest to use the command <code>ant debug</code> to build a debug version, since the SDK comes
1244    with a debug signing key. The result will be the file <code>Spinner/bin/SpinnerActivity-debug.apk</code>.
1245    You can install this to your device or emulator. Attach your device or start the emulator if you haven't already, and run the command:
1246<pre>
1247$ adb install Spinner/bin/SpinnerActivity-debug.apk
1248</pre>
1249  </li>
1250  <li>
1251    To create the test application, create a file <code>SpinnerActivityTest.java</code> in the directory
1252    <code>SpinnerActivityTest/src/com/android/example/spinner/test/</code>.
1253  </li>
1254  <li>
1255    Follow the tutorial, starting with the section <a href="#CreateTestCaseClass">Creating the Test Case Class</a>. When you are prompted to
1256    run the sample application, go to the Launcher screen in your device or emulator and select SpinnerActivity.
1257    When you are prompted to run the test application, return here to continue with the following instructions.
1258  </li>
1259  <li>
1260    Build the test application. If you are building with Ant, then it is easiest to use the command <code>ant debug</code> to build a
1261    debug version, since the SDK comes with a debug signing key. The result will be the Android file
1262    <code>SpinnerActivityTest/bin/SpinnerActivityTest-debug.apk</code>. You can install this to your device or emulator.
1263    Attach your device or start the emulator if you haven't already, and run the command:
1264<pre>
1265$ adb install SpinnerActivityTest/bin/SpinnerActivityTest-debug.apk
1266</pre>
1267  </li>
1268  <li>
1269    In your device or emulator, check that both the main application <code>SpinnerActivity</code> and the test application
1270    <code>SpinnerActivityTest</code> are installed.
1271  </li>
1272  <li>
1273    To run the test application, enter the following at the command line:
1274<pre>
1275$ adb shell am instrument -w com.android.example.spinner.test/android.test.InstrumentationTestRunner
1276 </pre>
1277  </li>
1278</ol>
1279<p>
1280    The result of a successful test looks like this:
1281</p>
1282<pre>
1283com.android.example.spinner.test.SpinnerActivityTest:....
1284Test results for InstrumentationTestRunner=....
1285Time: 10.098
1286OK (4 tests)
1287</pre>
1288<p>
1289    If you force the test to fail, as described in the previous section <a href="#TestFailure">Forcing Some Tests to Fail</a>, then
1290    the output looks like this:
1291</p>
1292<pre>
1293com.android.example.spinner.test.SpinnerActivityTest:
1294Failure in testPreConditions:
1295junit.framework.AssertionFailedError
1296  at com.android.example.spinner.test.SpinnerActivityTest.testPreConditions(SpinnerActivityTest.java:104)
1297  at java.lang.reflect.Method.invokeNative(Native Method)
1298  at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)
1299  at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)
1300  at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:175)
1301  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
1302  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
1303  at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)
1304  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
1305Failure in testSpinnerUI:
1306junit.framework.ComparisonFailure: expected:&lt;Result&gt; but was:&lt;Saturn&gt;
1307  at com.android.example.spinner.test.SpinnerActivityTest.testSpinnerUI(SpinnerActivityTest.java:153)
1308  at java.lang.reflect.Method.invokeNative(Native Method)
1309  at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:205)
1310  at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:195)
1311  at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:175)
1312  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
1313  at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
1314  at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)
1315  at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
1316..
1317Test results for InstrumentationTestRunner=.F.F..
1318Time: 9.377
1319FAILURES!!!
1320Tests run: 4,  Failures: 2,  Errors: 0
1321</pre>
1322