Home | History | Annotate | Download | only in activity-testing
      1 page.title=Creating and Running a Test Case
      2 trainingnavtop=true
      3 
      4 @jd:body
      5 
      6 <!-- This is the training bar -->
      7 <div id="tb-wrapper">
      8 <div id="tb">
      9 
     10 <h2>This lesson teaches you to</h2>
     11 <ol>
     12   <li><a href="#testcase">Create a Test Case for Activity Testing</a>
     13       <ol>
     14       <li><a href="#fixture">Set Up Your Test Fixture</a></li>
     15       <li><a href="#preconditions">Add Test Preconditions</a></li>
     16       <li><a href="#test_method">Add Test Methods to Verify Your Activity</a></li>
     17       </ol>
     18   </li>
     19   <li><a href="#build_run">Build and Run Your Test</a></li>
     20 </ol>
     21 
     22 <h2>You should also read</h2>
     23 <ul>
     24 <li><a href="{@docRoot}tools/testing/testing_android.html">Testing
     25 Fundamentals</a></li>
     26 </ul>
     27 
     28 </div>
     29 </div>
     30 <p>In order to verify that there are no regressions in the layout design and
     31 functional behavior in your application, it's important to
     32 create a test for each {@link android.app.Activity} in your application. For
     33 each test, you need to create the individual parts of a test case, including
     34 the test fixture, preconditions test method, and {@link android.app.Activity}
     35 test methods. You can then run your test to get a test report. If any test
     36 method fails, this might indicate a potential defect in your code.</p>
     37 <p class="note"><strong>Note:</strong> In the Test-Driven Development (TDD)
     38 approach, instead of writing most or all of your app code up-front and then
     39 running tests later in the development cycle, you would progressively write
     40 just enough production code to satisfy your test dependencies, update your
     41 test cases to reflect new functional requirements, and iterate repeatedly this
     42 way.</p>
     43 
     44 <h2 id="testcase">Create a Test Case</h2>
     45 <p>{@link android.app.Activity} tests are written in a structured way.
     46 Make sure to put your tests in a separate package, distinct from the code under
     47 test.</p>
     48 <p>By convention, your test package name should follow the same name as the
     49 application package, suffixed with <strong>".tests"</strong>. In the test package
     50 you created, add the Java class for your test case. By convention, your test case
     51 name should also follow the same name as the Java or Android class that you
     52 want to test, but suffixed with <strong>Test</strong>.</p>
     53 <p>To create a new test case in Eclipse:</p>
     54 <ol type="a">
     55    <li>In the Package Explorer, right-click on the {@code /src} directory for
     56 your test project and select <strong>New &gt; Package</strong>.</li>
     57    <li>Set the <strong>Name</strong> field to
     58 {@code &lt;your_app_package_name&gt;.tests} (for example,
     59 {@code com.example.android.testingfun.tests}) and click
     60 <strong>Finish</strong>.</li>
     61    <li>Right-click on the test package you created, and select
     62 <strong>New &gt; Class</strong>.</li>
     63     <li>Set the <strong>Name</strong> field to
     64 {@code &lt;your_app_activity_name&gt;Test} (for example,
     65 {@code MyFirstTestActivityTest}) and click <strong>Finish</strong>.</li>
     66 </ol>
     67 
     68 <h3 id="fixture">Set Up Your Test Fixture</h3>
     69 <p>A <em>test fixture</em> consists of objects that must be initialized for
     70 running one or more tests. To set up the test fixture, you can override the
     71 {@link junit.framework.TestCase#setUp()} and
     72 {@link junit.framework.TestCase#tearDown()} methods in your test. The
     73 test runner automatically runs {@link junit.framework.TestCase#setUp()} before
     74 running any other test methods, and {@link junit.framework.TestCase#tearDown()}
     75 at the end of each test method execution. You can use these methods to keep
     76 the code for test initialization and clean up separate from the tests methods.
     77 </p>
     78 <p>To set up your test fixture in Eclipse:</p>
     79 <ol>
     80 <li>In the Package Explorer, double-click on the test case that you created
     81 earlier to bring up the Eclipse Java editor, then modify your test case class
     82 to extend one of the sub-classes of {@link android.test.ActivityTestCase}.
     83 <p>For example:</p>
     84 <pre>
     85 public class MyFirstTestActivityTest
     86         extends ActivityInstrumentationTestCase2&lt;MyFirstTestActivity&gt; {
     87 </pre>
     88 </li>
     89 <li>Next, add the constructor and {@link junit.framework.TestCase#setUp()}
     90 methods to your test case, and add variable declarations for the
     91 {@link android.app.Activity} that you want to test.</p>
     92 <p>For example:</p>
     93 <pre>
     94 public class MyFirstTestActivityTest
     95         extends ActivityInstrumentationTestCase2&lt;MyFirstTestActivity&gt; {
     96 
     97     private MyFirstTestActivity mFirstTestActivity;
     98     private TextView mFirstTestText;
     99 
    100     public MyFirstTestActivityTest() {
    101         super(MyFirstTestActivity.class);
    102     }
    103 
    104     &#64;Override
    105     protected void setUp() throws Exception {
    106         super.setUp();
    107         mFirstTestActivity = getActivity();
    108         mFirstTestText =
    109                 (TextView) mFirstTestActivity
    110                 .findViewById(R.id.my_first_test_text_view);
    111     }
    112 }
    113 </pre>
    114 <p>The constructor is invoked by the test runner to instantiate the test
    115 class, while the {@link junit.framework.TestCase#setUp()} method is invoked by
    116 the test runner before it runs any tests in the test class.</p>
    117 </li>
    118 </ol>
    119 
    120 <p>Typically, in the {@link junit.framework.TestCase#setUp()} method, you
    121 should:</p>
    122 <ul>
    123 <li>Invoke the superclass constructor for
    124 {@link junit.framework.TestCase#setUp()}, which is required by JUnit.</li>
    125 <li>Initialize your test fixture state by:
    126    <ul>
    127    <li>Defining the instance variables that store the state of the fixture.</li>
    128    <li>Creating and storing a reference to an instance of the
    129 {@link android.app.Activity} under test.</li>
    130    <li>Obtaining a reference to any UI components in the
    131 {@link android.app.Activity} that you want to test.</li>
    132    </ul>
    133 </ul>
    134 
    135 <p>You can use the
    136 {@link android.test.ActivityInstrumentationTestCase2#getActivity()} method to
    137 get a reference to the {@link android.app.Activity} under test.</p>
    138 
    139 <h3 id="preconditions">Add Test Preconditions</h3>
    140 <p>As a sanity check, it is good practice to verify that the test fixture has
    141 been set up correctly, and the objects that you want to test have been correctly
    142 instantiated or initialized. That way, you wont have to see
    143 tests failing because something was wrong with the setup of your test fixture.
    144 By convention, the method for verifying your test fixture is called
    145 {@code testPreconditions()}.</p>
    146 
    147 <p>For example, you might want to add a {@code testPreconditons()} method like
    148 this to your test case:</p>
    149 
    150 <pre>
    151 public void testPreconditions() {
    152     assertNotNull(mFirstTestActivity is null, mFirstTestActivity);
    153     assertNotNull(mFirstTestText is null, mFirstTestText);
    154 }
    155 </pre>
    156 
    157 <p>The assertion methods are from the JUnit {@link junit.framework.Assert}
    158 class. Generally, you can use assertions to
    159 verify if a specific condition that you want to test is true.
    160 <ul>
    161 <li>If the condition is false, the assertion method throws an
    162 {@link android.test.AssertionFailedError} exception, which is then typically
    163 reported by the test runner. You can provide a string in the first argument of
    164 your assertion method to give some contextual details if the assertion fails.</li>
    165 <li>If the condition is true, the test passes.</li>
    166 </ul>
    167 <p>In both cases, the test runner proceeds to run the other test methods in the
    168 test case.</p>
    169 
    170 <h3 id="test_method">Add Test Methods to Verify Your Activity</h3>
    171 <p>Next, add one or more test methods to verify the layout and functional
    172 behavior of your {@link android.app.Activity}.</p>
    173 <p>For example, if your {@link android.app.Activity} includes a
    174 {@link android.widget.TextView}, you can add a test method like this to check
    175 that it has the correct label text:</p>
    176 <pre>
    177 public void testMyFirstTestTextView_labelText() {
    178     final String expected =
    179             mFirstTestActivity.getString(R.string.my_first_test);
    180     final String actual = mFirstTestText.getText().toString();
    181     assertEquals(expected, actual);
    182 }
    183 </pre>
    184 
    185 <p>The {@code testMyFirstTestTextView_labelText()} method simply checks that the
    186 default text of the {@link android.widget.TextView} that is set by the layout
    187 is the same as the expected text defined in the {@code strings.xml} resource.</p>
    188 <p class="note"><strong>Note:</strong> When naming test methods, you can use
    189 an underscore to separate what is being tested from the specific case being
    190 tested. This style makes it easier to see exactly what cases are being tested.</p>
    191 <p>When doing this type of string value comparison, its good practice to read
    192 the expected string from your resources, instead of hardcoding the string in
    193 your comparison code. This prevents your test from easily breaking whenever the
    194 string definitions are modified in the resource file.</p>
    195 <p>To perform the comparison, pass both the expected and actual strings as
    196 arguments to the
    197 {@link junit.framework.Assert#assertEquals(java.lang.String, java.lang.String) assertEquals()}
    198 method. If the values are not the same, the assertion will throw an
    199 {@link junit.framework.AssertionFailedError} exception.</p>
    200 <p>If you added a {@code testPreconditions()} method, put your test methods
    201 after the {@code testPreconditions()} definition in your Java class.</p>
    202 <p>For a complete test case example, take a look at
    203 {@code MyFirstTestActivityTest.java} in the sample app.</p>
    204 
    205 <h2 id="build_run">Build and Run Your Test</h2>
    206 <p>You can build and run your test easily from the Package Explorer in
    207 Eclipse.</p>
    208 <p>To build and run your test:</p>
    209 <ol>
    210 <li>Connect an Android device to your machine. On the device or emulator, open
    211 the <strong>Settings</strong> menu, select <strong>Developer options</strong>
    212 and make sure that USB debugging is enabled.</li>
    213 <li>In the Project Explorer, right-click on the test class that you created
    214 earlier and select <strong>Run As &gt; Android Junit Test</strong>.</li>
    215 <li>In the Android Device Chooser dialog, select the device that you just
    216 connected, then click <strong>OK</strong>.</li>
    217 <li>In the JUnit view, verify that the test passes with no errors or failures.</li>
    218 </ol>
    219 <p>For example, if the test case passes with no errors, the result should look
    220 like this:</p>
    221 <img src="{@docRoot}images/training/activity-testing_lesson2_MyFirstTestActivityTest_result.png" alt="" />
    222 <p class="img-caption">
    223   <strong>Figure 1.</strong> Result of a test with no errors.
    224 </p>
    225 
    226 
    227 
    228