• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Building Instrumented Unit Tests
2page.tags=testing,androidjunitrunner,junit,unit test,mock,instrumentation
3trainingnavtop=true
4
5@jd:body
6
7<!-- This is the training bar -->
8<div id="tb-wrapper">
9<div id="tb">
10  <h2>Dependencies and Prerequisites</h2>
11
12  <ul>
13    <li>Android 2.2 (API level 8) or higher</li>
14    <li><a href="{@docRoot}tools/testing-support-library/index.html">
15      Android Testing Support Library</a></li>
16  </ul>
17
18  <h2>This lesson teaches you to</h2>
19
20  <ol>
21    <li><a href="#setup">Set Up Your Testing Environment</a></li>
22    <li><a href="#build">Create a Instrumented Unit Test Class</a></li>
23    <li><a href="#run">Run Instrumented Unit Tests</a></li>
24  </ol>
25
26  <h2>Try it out</h2>
27
28  <ul>
29    <li>
30<a href="https://github.com/googlesamples/android-testing/tree/master/unittesting/BasicUnitAndroidTest"
31class="external-link">Instrumented Unit Tests Code Samples</a></li>
32  </ul>
33</div>
34</div>
35
36<p>
37Instrumented unit tests are unit tests that run on physical devices and emulators, instead of
38the Java Virtual Machine (JVM) on your local machine. You should create instrumented unit tests
39if your tests need access to instrumentation information (such as the target app's
40{@link android.content.Context}) or if they require the real implementation of an Android framework
41component (such as a {@link android.os.Parcelable} or {@link android.content.SharedPreferences}
42object). Using instrumented unit tests also helps to reduce the effort required to write and
43maintain mock code. You are still free to use a mocking framework, if you choose, to simulate any
44dependency relationships. Instrumented unit tests can take advantage of the Android framework APIs
45and supporting APIs, such as the Android Testing Support Library.
46</p>
47
48<h2 id="setup">Set Up Your Testing Environment</h2>
49<p>Before building instrumented unit tests, you must:</p>
50
51  <ul>
52      <li>
53        <strong>Install the Android Testing Support Library</strong>. The
54        <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
55        {@code AndroidJUnitRunner}</a> API, located under the
56        {@code com.android.support.test.runner} package, allows you to
57        create and run instrumented unit tests.  To learn how to install the
58        library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup">
59        Testing Support Library Setup</a>.
60      </li>
61
62      <li>
63        <strong>Set up your project structure.</strong> In your Gradle project, the source code for
64        the target app that you want to test is typically placed under the {@code app/src/main/java}
65        folder. The source code for instrumentatation tests, including your unit tests, must be
66        placed under the <code>app/src/androidTest/java</code> folder.
67        To learn more about setting up your project directory, see
68        <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.
69      </li>
70
71      <li>
72        <strong>Specify your Android testing dependencies</strong>. In order for the
73        <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to
74        correctly build and run your instrumented unit tests, you must specify the following
75        libraries in the {@code build.gradle} file of your Android app module:
76
77        <pre>
78dependencies {
79    androidTestCompile 'com.android.support.test:runner:0.3'
80    androidTestCompile 'com.android.support.test:rules:0.3'
81    // Set this dependency if you want to use Hamcrest matching
82    androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
83}
84</pre>
85      </li>
86  </ul>
87
88<h2 id="build">Create an Instrumented Unit Test Class</h2>
89<p>
90Your instrumented unit test class should be written as a JUnit 4 test class. To learn more about
91creating JUnit 4 test classes and using JUnit 4 assertions and annotations, see
92<a href="local-unit-tests.html#build">Create a Local Unit Test Class</a>.
93</p>
94<p>To create an instrumented JUnit 4 test class, add the {@code &#64;RunWith(AndroidJUnit4.class)}
95annotation at the beginning of your test class definition. You also need to specify the
96<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
97{@code AndroidJUnitRunner}</a> class
98provided in the Android Testing Support Library as your default test runner. This step is described
99in more detail in <a href="#run">Run Instrumented Unit Tests</a>.
100</p>
101
102<p>The following example shows how you might write an instrumented unit test to test that
103the {@link android.os.Parcelable} interface is implemented correctly for the
104{@code LogHistory} class:</p>
105
106<pre>
107import android.os.Parcel;
108import android.support.test.runner.AndroidJUnit4;
109import android.util.Pair;
110import org.junit.Test;
111import org.junit.runner.RunWith;
112import java.util.List;
113import static org.hamcrest.Matchers.is;
114import static org.junit.Assert.assertThat;
115
116&#64;RunWith(AndroidJUnit4.class)
117public class LogHistoryAndroidUnitTest {
118
119    public static final String TEST_STRING = "This is a string";
120    public static final long TEST_LONG = 12345678L;
121    private LogHistory mLogHistory;
122
123    &#64;Before
124    public void createLogHistory() {
125        mLogHistory = new LogHistory();
126    }
127
128    &#64;Test
129    public void logHistory_ParcelableWriteRead() {
130        // Set up the Parcelable object to send and receive.
131        mLogHistory.addEntry(TEST_STRING, TEST_LONG);
132
133        // Write the data.
134        Parcel parcel = Parcel.obtain();
135        mLogHistory.writeToParcel(parcel, mLogHistory.describeContents());
136
137        // After you're done with writing, you need to reset the parcel for reading.
138        parcel.setDataPosition(0);
139
140        // Read the data.
141        LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel);
142        List&lt;Pair&lt;String, Long&gt;&gt; createdFromParcelData = createdFromParcel.getData();
143
144        // Verify that the received data is correct.
145        assertThat(createdFromParcelData.size(), is(1));
146        assertThat(createdFromParcelData.get(0).first, is(TEST_STRING));
147        assertThat(createdFromParcelData.get(0).second, is(TEST_LONG));
148    }
149}
150</pre>
151
152<h3 id="test-suites">Creating a test suite</h3>
153<p>
154To organize the execution of your instrumented unit tests, you can group a collection of test
155classes in a <em>test suite</em> class and run these tests together. Test suites can be nested;
156your test suite can group other test suites and run all their component test classes together.
157</p>
158
159<p>
160A test suite is contained in a test package, similar to the main application package. By
161convention, the test suite package name usually ends with the {@code .suite} suffix (for example,
162{@code com.example.android.testing.mysample.suite}).
163</p>
164
165<p>
166To create a test suite for your unit tests, import the JUnit
167<a href="http://junit.sourceforge.net/javadoc/org/junit/runner/RunWith.html"
168class="external-link">{@code RunWith}</a> and
169<a href="http://junit.sourceforge.net/javadoc/org/junit/runners/Suite.html"
170class="external-link">{@code Suite}</a> classes. In your test suite, add the
171{@code &#64;RunWith(Suite.class)} and the {@code &#64;Suite.SuitClasses()} annotations. In
172the {@code &#64;Suite.SuiteClasses()} annotation, list the individual test classes or test
173suites as arguments.
174</p>
175
176<p>
177The following example shows how you might implement a test suite called {@code UnitTestSuite}
178that groups and runs the {@code CalculatorInstrumentationTest} and
179{@code CalculatorAddParameterizedTest} test classes together.
180</p>
181
182<pre>
183import com.example.android.testing.mysample.CalculatorAddParameterizedTest;
184import com.example.android.testing.mysample.CalculatorInstrumentationTest;
185import org.junit.runner.RunWith;
186import org.junit.runners.Suite;
187
188// Runs all unit tests.
189&#64;RunWith(Suite.class)
190&#64;Suite.SuiteClasses({CalculatorInstrumentationTest.class,
191        CalculatorAddParameterizedTest.class})
192public class UnitTestSuite {}
193</pre>
194
195<h2 id="run">Run Instrumented Unit Tests</h2>
196<p>
197The
198<a href="https://developer.android.com/tools/building/plugin-for-gradle.html">
199  Android Plug-in for Gradle</a>
200provides a default directory ({@code src/androidTest/java}) for you to store the instrumented unit
201and integration test classes and test suites that you want to run on a device. The plug-in compiles
202the test code in that directory and then executes the test app using a test runner class. You must
203set the
204<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
205{@code AndroidJUnitRunner}</a> class provided in the
206<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>
207as your default test runner.</p>
208</p>
209
210<p>To specify
211<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
212{@code AndroidJUnitRunner}</a> as the default test instrumentation runner, add the following
213setting in your {@code build.gradle} file:</p>
214<pre>
215android {
216    defaultConfig {
217        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
218    }
219}
220</pre>
221
222<h3 id="run-from-Android-Studio">Running instrumented unit tests from Android Studio</h3>
223<p>
224To run instrumented unit tests in your Gradle project from Android Studio:
225</p>
226<ol>
227<li>Open the <strong>Build Variants</strong> window by clicking the left-hand tab, then set the
228test artifact to <em>Android Instrumentation Tests</em>.
229</li>
230<li>In the <strong>Project</strong> window, drill down to your unit test class or method, then
231  right-click and run it using the Android Test configuration.
232</li>
233</ol>
234
235<p>Android Studio displays the results of the unit test execution in the <strong>Run</strong>
236window.</p>
237
238<h3 id="run-from-commandline">Running instrumented unit tests from the command-line</h3>
239
240<p>To run instrumented unit tests in your Gradle project from the command-line, call the
241  {@code connectedCheck} (or {@code cC}) task:</p>
242
243<pre>
244./gradlew cC
245</pre>
246
247<p>You can find the generated HTML test result reports in the
248{@code &lt;path_to_your_project&gt;/app/build/outputs/reports/androidTests/connected/} directory,
249and the corresponding XML files in the
250{@code &lt;path_to_your_project&gt;/app/build/outputs/androidTest-results/connected/} directory.</p>