| page.title=Building Instrumented Unit Tests |
| page.tags=testing,androidjunitrunner,junit,unit test,mock,instrumentation |
| trainingnavtop=true |
| |
| @jd:body |
| |
| <!-- This is the training bar --> |
| <div id="tb-wrapper"> |
| <div id="tb"> |
| <h2>This lesson teaches you to</h2> |
| |
| <ol> |
| <li><a href="#setup">Set Up Your Testing Environment</a></li> |
| <li><a href="#build">Create a Instrumented Unit Test Class</a> |
| <ol> |
| <li><a href="#test-suites">Create a test suite</a></li> |
| </ol> |
| </li> |
| <li><a href="#run">Run Instrumented Unit Tests</a> |
| <ol> |
| <li><a href="#run-ctl">Run your tests with Firebase Test Lab</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>Try it out</h2> |
| |
| <ul> |
| <li> |
| <a href="https://github.com/googlesamples/android-testing/tree/master/unit/BasicUnitAndroidTest" |
| class="external-link">Instrumented Unit Tests Code Samples</a></li> |
| <li><a href="https://www.code-labs.io/codelabs/android-studio-testing/index.html?index=..%2F..%2Findex#0" |
| class="external-link">Unit and UI Testing in Android Studio (codelab)</a></li> |
| </ul> |
| </div> |
| </div> |
| |
| <p>Instrumented unit tests are tests that run on physical devices and |
| emulators, and they can take advantage of the Android framework APIs and |
| supporting APIs, such as the Android Testing Support Library. You should create |
| instrumented unit tests if your tests need access to instrumentation |
| information (such as the target app's {@link android.content.Context}) or if |
| they require the real implementation of an Android framework component (such as |
| a {@link android.os.Parcelable} or {@link android.content.SharedPreferences} |
| object).</p> |
| |
| <p>Using instrumented unit tests also helps to reduce the effort required to |
| write and maintain mock code. You are still free to use a mocking framework, if |
| you choose, to simulate any dependency relationships.</p> |
| |
| |
| <h2 id="setup">Set Up Your Testing Environment</h2> |
| |
| <p>In your Android Studio project, you must store the source files for |
| instrumented tests at |
| <code><var>module-name</var>/src/androidTests/java/</code>. This directory |
| already exists when you create a new project.</p> |
| |
| <p>Before you begin, you should |
| <a href="{@docRoot}tools/testing-support-library/index.html#setup">download |
| the Android Testing Support Library Setup</a>, which provides APIs that allow |
| you to quickly build and run instrumented test code for your apps. The |
| Testing Support Library includes a JUnit 4 test runner (<a href= |
| "{@docRoot}tools/testing-support-library/index.html#AndroidJUnitRunner">AndroidJUnitRunner</a> |
| ) and APIs for functional UI tests (<a href= |
| "{@docRoot}tools/testing-support-library/index.html#Espresso">Espresso</a> |
| and <a href= |
| "{@docRoot}tools/testing-support-library/index.html#UIAutomator">UI |
| Automator</a>). |
| </p> |
| |
| <p>You also need to configure the Android testing dependencies for your project |
| to use the test runner and the rules APIs provided by the Testing Support |
| Library. To simplify your test development, you should also include the |
| <a href="https://github.com/hamcrest" class="external-link">Hamcrest</a> |
| library, which lets you create more flexible assertions using the Hamcrest |
| matcher APIs.</p> |
| |
| <p> |
| In your app's top-level {@code build.gradle} file, you need to specify these |
| libraries as dependencies: |
| </p> |
| |
| <pre> |
| dependencies { |
| androidTestCompile 'com.android.support:support-annotations:24.0.0' |
| androidTestCompile 'com.android.support.test:runner:0.5' |
| androidTestCompile 'com.android.support.test:rules:0.5' |
| // Optional -- Hamcrest library |
| androidTestCompile 'org.hamcrest:hamcrest-library:1.3' |
| // Optional -- UI testing with Espresso |
| androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' |
| // Optional -- UI testing with UI Automator |
| androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2' |
| } |
| </pre> |
| |
| |
| <p> |
| To use JUnit 4 test classes, make sure to specify <a href= |
| "{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code |
| AndroidJUnitRunner}</a> as the default test instrumentation runner in your |
| project by including the following setting in your app's module-level {@code build.gradle} |
| file: |
| </p> |
| |
| <pre> |
| android { |
| defaultConfig { |
| testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" |
| } |
| } |
| </pre> |
| |
| |
| |
| |
| <h2 id="build">Create an Instrumented Unit Test Class</h2> |
| |
| <p> |
| Your instrumented unit test class should be written as a JUnit 4 test class. To learn more about |
| creating JUnit 4 test classes and using JUnit 4 assertions and annotations, see |
| <a href="local-unit-tests.html#build">Create a Local Unit Test Class</a>. |
| </p> |
| <p>To create an instrumented JUnit 4 test class, add the {@code @RunWith(AndroidJUnit4.class)} |
| annotation at the beginning of your test class definition. You also need to specify the |
| <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html"> |
| {@code AndroidJUnitRunner}</a> class |
| provided in the Android Testing Support Library as your default test runner. This step is described |
| in more detail in <a href="{@docRoot}training/testing/start/index.html#run-instrumented-tests"> |
| Getting Started with Testing</p> |
| |
| <p>The following example shows how you might write an instrumented unit test to test that |
| the {@link android.os.Parcelable} interface is implemented correctly for the |
| {@code LogHistory} class:</p> |
| |
| <pre> |
| import android.os.Parcel; |
| import android.support.test.runner.AndroidJUnit4; |
| import android.util.Pair; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import java.util.List; |
| import static org.hamcrest.Matchers.is; |
| import static org.junit.Assert.assertThat; |
| |
| @RunWith(AndroidJUnit4.class) |
| @SmallTest |
| public class LogHistoryAndroidUnitTest { |
| |
| public static final String TEST_STRING = "This is a string"; |
| public static final long TEST_LONG = 12345678L; |
| private LogHistory mLogHistory; |
| |
| @Before |
| public void createLogHistory() { |
| mLogHistory = new LogHistory(); |
| } |
| |
| @Test |
| public void logHistory_ParcelableWriteRead() { |
| // Set up the Parcelable object to send and receive. |
| mLogHistory.addEntry(TEST_STRING, TEST_LONG); |
| |
| // Write the data. |
| Parcel parcel = Parcel.obtain(); |
| mLogHistory.writeToParcel(parcel, mLogHistory.describeContents()); |
| |
| // After you're done with writing, you need to reset the parcel for reading. |
| parcel.setDataPosition(0); |
| |
| // Read the data. |
| LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel); |
| List<Pair<String, Long>> createdFromParcelData = createdFromParcel.getData(); |
| |
| // Verify that the received data is correct. |
| assertThat(createdFromParcelData.size(), is(1)); |
| assertThat(createdFromParcelData.get(0).first, is(TEST_STRING)); |
| assertThat(createdFromParcelData.get(0).second, is(TEST_LONG)); |
| } |
| } |
| </pre> |
| |
| <h3 id="test-suites">Create a test suite</h3> |
| <p> |
| To organize the execution of your instrumented unit tests, you can group a collection of test |
| classes in a <em>test suite</em> class and run these tests together. Test suites can be nested; |
| your test suite can group other test suites and run all their component test classes together. |
| </p> |
| |
| <p> |
| A test suite is contained in a test package, similar to the main application package. By |
| convention, the test suite package name usually ends with the {@code .suite} suffix (for example, |
| {@code com.example.android.testing.mysample.suite}). |
| </p> |
| |
| <p> |
| To create a test suite for your unit tests, import the JUnit |
| <a href="http://junit.sourceforge.net/javadoc/org/junit/runner/RunWith.html" |
| class="external-link">{@code RunWith}</a> and |
| <a href="http://junit.sourceforge.net/javadoc/org/junit/runners/Suite.html" |
| class="external-link">{@code Suite}</a> classes. In your test suite, add the |
| {@code @RunWith(Suite.class)} and the {@code @Suite.SuitClasses()} annotations. In |
| the {@code @Suite.SuiteClasses()} annotation, list the individual test classes or test |
| suites as arguments. |
| </p> |
| |
| <p> |
| The following example shows how you might implement a test suite called {@code UnitTestSuite} |
| that groups and runs the {@code CalculatorInstrumentationTest} and |
| {@code CalculatorAddParameterizedTest} test classes together. |
| </p> |
| |
| <pre> |
| import com.example.android.testing.mysample.CalculatorAddParameterizedTest; |
| import com.example.android.testing.mysample.CalculatorInstrumentationTest; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.Suite; |
| |
| // Runs all unit tests. |
| @RunWith(Suite.class) |
| @Suite.SuiteClasses({CalculatorInstrumentationTest.class, |
| CalculatorAddParameterizedTest.class}) |
| public class UnitTestSuite {} |
| </pre> |
| |
| |
| <h2 id="run">Run Instrumented Unit Tests</h2> |
| |
| <p>To run your instrumented tests, follow these steps:</p> |
| |
| <ol> |
| <li>Be sure your project is synchronized with Gradle by clicking |
| <b>Sync Project</b> <img src="/images/tools/sync-project.png" alt="" |
| class="inline-icon"> in the toolbar.</li> |
| |
| <li>Run your test in one of the following ways: |
| <ul> |
| <li>To run a single test, open the <b>Project</b> window, and then |
| right-click a test and click <strong>Run</strong> <img src= |
| "{@docRoot}images/tools/as-run.png" alt="" class="inline-icon">.</li> |
| <li>To test all methods in a class, right-click a class or method in the |
| test file and click <b>Run</b> <img src= |
| "{@docRoot}images/tools/as-run.png" alt="" class="inline-icon">. |
| <li>To run all tests in a directory, right-click on the |
| directory and select <strong>Run tests</strong> <img src= |
| "{@docRoot}images/tools/as-run.png" alt="" class="inline-icon">. |
| </li> |
| </ul> |
| </li> |
| |
| </ol> |
| |
| <p> |
| The <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plugin |
| for Gradle</a> compiles the instrumented test code located in the default |
| directory ({@code src/androidTest/java/}), builds a test APK and production |
| APK, installs both APKs on the connected device or emulator, and runs the |
| tests. Android Studio then displays the results of the instrumented test execution in the |
| <em>Run</em> window. |
| </p> |
| |
| <p class="note"> |
| <strong>Note:</strong> While running or debugging instrumented tests, |
| Android Studio does not inject the additional methods required for <a href= |
| "{@docRoot}tools/building/building-studio.html#instant-run">Instant Run</a> |
| and turns the feature off. |
| </p> |
| |
| |
| <h3 id="run-ctl">Run your tests with Firebase Test Lab</h3> |
| |
| <p>Using <a href="https://firebase.google.com/docs/test-lab/">Firebase Test |
| Lab</a>, you can simultaneously test your app on many popular Android devices |
| and configurations such as locale, orientation, screen size, and platform |
| version. These tests run on actual physical devices in remote Google data |
| centers. You can deploy to Firebase Test Lab directly from Android Studio or |
| from the command line. Test results provide test logs and include the details |
| of any app failures.</p> |
| |
| <p> |
| Before you can start using Firebase Test Lab, you need to: |
| </p> |
| |
| <ol> |
| <li> |
| <a href="https://console.developers.google.com/freetrial">Create a |
| Google Cloud Platform account</a> to use with active billing. |
| </li> |
| |
| <li> |
| <a href="https://support.google.com/cloud/answer/6251787">Create a Google |
| Cloud project</a> for your app. |
| </li> |
| |
| <li> |
| <a href="https://support.google.com/cloud/answer/6288653">Set up an active |
| billing account</a> and associate it with the project you just created. |
| </li> |
| </ol> |
| |
| |
| <h4 id="configure-matrix"> |
| Configure a test matrix and run a test |
| </h4> |
| |
| <p> |
| Android Studio provides integrated tools that allow you to configure how you |
| want to deploy your tests to Firebase Test Lab. After you have created a Google |
| Cloud project with active billing, you can create a test configuration and |
| run your tests: |
| </p> |
| |
| <ol> |
| <li>Click <strong>Run</strong> > <strong>Edit Configurations</strong> from |
| the main menu. |
| </li> |
| |
| <li>Click <strong>Add New Configuration (+)</strong> and select |
| <strong>Android Tests</strong>. |
| </li> |
| |
| <li>In the Android Test configuration dialog: |
| <ol type="a"> |
| <li>Enter or select the details of your test, such as the test name, module |
| type, test type, and test class. |
| </li> |
| |
| <li>From the <em>Target</em> drop-down menu under <em>Deployment Target |
| Options</em>, select <strong>Cloud Test Lab Device Matrix</strong>. |
| </li> |
| |
| <li>If you are not logged in, click <strong>Connect to Google Cloud |
| Platform</strong> and allow Android Studio access to your account. |
| </li> |
| |
| <li>Next to <em>Cloud Project</em>, click the <img src= |
| "{@docRoot}images/tools/as-wrench.png" alt="wrench and nut" style= |
| "vertical-align:bottom;margin:0;"> button and select your Google Cloud |
| Platform project from the list. |
| </li> |
| </ol> |
| </li> |
| |
| <li>Create and configure a test matrix: |
| <ol type="a"> |
| <li>Next to the <em>Matrix Configuration</em> drop-down list, click <strong> |
| Open Dialog</strong> <img src="{@docRoot}images/tools/as-launchavdm.png" |
| alt="ellipses button" style="vertical-align:bottom;margin:0;">. |
| </li> |
| |
| <li>Click <strong>Add New Configuration (+)</strong>. |
| </li> |
| |
| <li>In the <strong>Name</strong> field, enter a name for your new |
| configuration. |
| </li> |
| |
| <li>Select the device(s), Android version(s), locale(s) and screen |
| orientation(s) that you want to test your app with. Firebase Test Lab will |
| test your app against every combination of your selections when generating |
| test results. |
| </li> |
| |
| <li>Click <strong>OK</strong> to save your configuration. |
| </li> |
| </ol> |
| </li> |
| |
| <li>Click <strong>OK</strong> in the <em>Run/Debug Configurations</em> dialog |
| to exit. |
| </li> |
| |
| <li>Run your tests by clicking <strong>Run</strong> <img src= |
| "{@docRoot}images/tools/as-run.png" alt="" style= |
| "vertical-align:bottom;margin:0;">. |
| </li> |
| </ol> |
| |
| <img src="{@docRoot}images/training/ctl-config.png" alt=""> |
| <p class="img-caption"> |
| <strong>Figure 1.</strong> Creating a test configuration for Firebase Test |
| Lab. |
| </p> |
| |
| <h4 id="ctl-results"> |
| Analyzing test results |
| </h4> |
| |
| <p> |
| When Firebase Test Lab completes running your tests, the <em>Run</em> window |
| will open to show the results, as shown in figure 2. You may need to click |
| <strong>Show Passed</strong> <img src="{@docRoot}images/tools/as-ok.png" alt= |
| "" style="vertical-align:bottom;margin:0;"> to see all your executed tests. |
| </p> |
| |
| <img src="{@docRoot}images/training/ctl-test-results.png" alt=""> |
| |
| <p class="img-caption"> |
| <strong>Figure 2.</strong> Viewing the results of instrumented tests using |
| Firebase Test Lab. |
| </p> |
| |
| <p> |
| You can also analyze your tests on the web by following the link displayed at |
| the beginning of the test execution log in the <em>Run</em> window, as shown |
| in figure 3. |
| </p> |
| |
| <img src="{@docRoot}images/training/ctl-exec-log.png" alt=""> |
| |
| <p class="img-caption"> |
| <strong>Figure 3.</strong> Click the link to view detailed test results on |
| the web. |
| </p> |
| |
| <p> |
| To learn more about interpreting web results, see <a href= |
| "https://firebase.google.com/docs/test-lab/analyzing-results">Analyze |
| Firebase Test Lab for Android Results</a>. |
| </p> |