Show navigation Hide navigation

Building Instrumented Unit Tests

Dependencies and Prerequisites

This lesson teaches you to

  1. Set Up Your Testing Environment
  2. Create a Instrumented Unit Test Class
  3. Run Instrumented Unit Tests

Try it out

Instrumented unit tests are unit tests that run on physical devices and emulators, instead of the Java Virtual Machine (JVM) on your local machine. You should create instrumented unit tests if your tests need access to instrumentation information (such as the target app's Context) or if they require the real implementation of an Android framework component (such as a Parcelable or SharedPreferences object). 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. Instrumented unit tests can take advantage of the Android framework APIs and supporting APIs, such as the Android Testing Support Library.

Set Up Your Testing Environment

Before building instrumented unit tests, you must:

  • Install the Android Testing Support Library. The AndroidJUnitRunner API, located under the com.android.support.test.runner package, allows you to create and run instrumented unit tests. To learn how to install the library, see Testing Support Library Setup.
  • Set up your project structure. In your Gradle project, the source code for the target app that you want to test is typically placed under the app/src/main/java folder. The source code for instrumentatation tests, including your unit tests, must be placed under the app/src/androidTest/java folder. To learn more about setting up your project directory, see Managing Projects.
  • Specify your Android testing dependencies. In order for the Android Plug-in for Gradle to correctly build and run your instrumented unit tests, you must specify the following libraries in the build.gradle file of your Android app module:
    dependencies {
        androidTestCompile 'com.android.support.test:runner:0.3'
        androidTestCompile 'com.android.support.test:rules:0.3'
        // Set this dependency if you want to use Hamcrest matching
        androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
    }
    

Create an Instrumented Unit Test Class

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 Create a Local Unit Test Class.

To create an instrumented JUnit 4 test class, add the @RunWith(AndroidJUnit4.class) annotation at the beginning of your test class definition. You also need to specify the AndroidJUnitRunner class provided in the Android Testing Support Library as your default test runner. This step is described in more detail in Run Instrumented Unit Tests.

The following example shows how you might write an instrumented unit test to test that the Parcelable interface is implemented correctly for the LogHistory class:

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)
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));
    }
}

Creating a test suite

To organize the execution of your instrumented unit tests, you can group a collection of test classes in a test suite 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.

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 .suite suffix (for example, com.example.android.testing.mysample.suite).

To create a test suite for your unit tests, import the JUnit RunWith and Suite classes. In your test suite, add the @RunWith(Suite.class) and the @Suite.SuitClasses() annotations. In the @Suite.SuiteClasses() annotation, list the individual test classes or test suites as arguments.

The following example shows how you might implement a test suite called UnitTestSuite that groups and runs the CalculatorInstrumentationTest and CalculatorAddParameterizedTest test classes together.

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 {}

Run Instrumented Unit Tests

The Android Plug-in for Gradle provides a default directory (src/androidTest/java) for you to store the instrumented unit and integration test classes and test suites that you want to run on a device. The plug-in compiles the test code in that directory and then executes the test app using a test runner class. You must set the AndroidJUnitRunner class provided in the Android Testing Support Library as your default test runner.

To specify AndroidJUnitRunner as the default test instrumentation runner, add the following setting in your build.gradle file:

android {
    defaultConfig {
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}

Running instrumented unit tests from Android Studio

To run instrumented unit tests in your Gradle project from Android Studio:

  1. Open the Build Variants window by clicking the left-hand tab, then set the test artifact to Android Instrumentation Tests.
  2. In the Project window, drill down to your unit test class or method, then right-click and run it using the Android Test configuration.

Android Studio displays the results of the unit test execution in the Run window.

Running instrumented unit tests from the command-line

To run instrumented unit tests in your Gradle project from the command-line, call the connectedCheck (or cC) task:

./gradlew cC

You can find the generated HTML test result reports in the <path_to_your_project>/app/build/outputs/reports/androidTests/connected/ directory, and the corresponding XML files in the <path_to_your_project>/app/build/outputs/androidTest-results/connected/ directory.