| quddusc | 2ef3952 | 2013-06-21 16:49:46 -0700 | [diff] [blame] | 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 > Package</strong>.</li> |
| 57 | <li>Set the <strong>Name</strong> field to |
| 58 | {@code <your_app_package_name>.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 > Class</strong>.</li> |
| 63 | <li>Set the <strong>Name</strong> field to |
| 64 | {@code <your_app_activity_name>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<MyFirstTestActivity> { |
| 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<MyFirstTestActivity> { |
| 96 | |
| 97 | private MyFirstTestActivity mFirstTestActivity; |
| 98 | private TextView mFirstTestText; |
| 99 | |
| 100 | public MyFirstTestActivityTest() { |
| 101 | super(MyFirstTestActivity.class); |
| 102 | } |
| 103 | |
| 104 | @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 won’t 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, it’s 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 > 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 | |