Skip to content

Instrumentation Tests Setup

Marcel Schnelle edited this page Jul 31, 2021 · 6 revisions

Important Note ⚠️

JUnit 5 requires an environment built on top of Java 8. For Android, this means that devices running Android 8.0/API 26/Oreo are supported, and can execute JUnit 5 instrumentation tests just fine - older devices can not. Check out this page for more info.

Instrumentation Tests with JUnit 5

Instrumentation tests are executed on an actual Android device, or emulator. In contrast to unit tests, these tests can interact with platform capabilities, as well as classes provided by the Android SDK. To help you write instrumentation tests with JUnit 5, there are a few helper libraries. This guide describes the necessary steps to set this up.

1. Add the libraries

The following libraries have to be added to your dependencies block. Make sure to check for updates to each of these artifacts, as this guide may use outdated versions:

dependencies {
    androidTestImplementation("androidx.test:runner:1.4.0")
    androidTestImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2")

    androidTestImplementation("de.mannodermaus.junit5:android-test-core:1.2.2")
    androidTestRuntimeOnly("de.mannodermaus.junit5:android-test-runner:1.2.2")
}

Note how the JUnit 5 library is split into two parts: There is the android-test-core, which is a small library to interact with the ActivityScenario API, providing the necessary setup to configure an Android project. Furthermore, the android-test-runner library is responsible for detecting & executing JUnit 5 tests on supported devices (note the usage of androidTestRuntimeOnly, instead of androidTestImplementation here).

2. Use the AndroidX Test Runner

One of the more obscure and unknown features of Android's test support is the ability to pass custom arguments to the TestRunner for instrumentation tests. The runner library takes advantage of this feature, and registers itself as a host for tests. Add the following to your android.defaultConfig block:

android {
    defaultConfig {
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        testInstrumentationRunnerArgument("runnerBuilder", "de.mannodermaus.junit5.AndroidJUnit5Builder")
    }
}

3. Enable Java 8

When you set up the Gradle plugin for JUnit 5 on Android, you should have already done this step. However, for completeness sake, let's review the fact that Java 8 is the basis for all code in your module. Add the following statements to your build script:

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
    }
}

4. Sync

Sync your Gradle project, and the dependencies will be available in your androidTest source set!

Troubleshooting

The plugin will assist you with the installation of instrumentation tests into your project, by raising an error during Gradle Sync when it detects that something is wwrong about the project's configuration.

If you have added the testInstrumentationRunnerArgument to your build (Step 2 in the list above), but the dependency cannot be found in the androidTestRuntimeOnly configuration (Step 1 in the list above), or the other way around, you are presented with one of the following errors:

Gradle sync failed: Incomplete configuration for JUnit 5 instrumentation tests:
Add the android-test-runner library to the androidTestRuntimeOnly configuration's dependencies.
Find more information at: https://bit.ly/junit5-instrumentation-tests

In this case, please review your build file and the instructions, and try again.

Disabling the automatic check

In case you need to deviate from the usual set-up for instrumentation tests, you can tell the Gradle plugin to stop raising errors. To achieve this, use the integrityCheckEnabled DSL in the plugin's configuration block, as shown below. This functionality is reserved for advanced users who may utilize a custom dependency structure, where the android-test-runner dependency isn't applied directly in the build script, for example.

junitPlatform {
    // Don't raise errors about incorrect configuration
    // of JUnit 5 instrumentation tests
    instrumentationTests {
        integrityCheckEnabled = false
    }
}