AndroidX : No instrumentation registered! Must run under a registering instrumentation

I'm trying to run a local unit test that depends on the context, and was following this guide: https://developer.android.com/training/testing/unit-testing/local-unit-tests#kotlin and I set up my project like this (following this link : https://developer.android.com/training/testing/set-up-project ):

build.gradle(app)

android {
compileSdkVersion 28
buildToolsVersion '27.0.3'
defaultConfig {
    minSdkVersion 21
    targetSdkVersion 27
    versionCode 76
    versionName "2.6.0"
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    multiDexEnabled true

useLibrary 'android.test.runner'
    useLibrary 'android.test.base'
    useLibrary 'android.test.mock'

}
testOptions {
    unitTests.returnDefaultValues = true
    unitTests.all {
        // All the usual Gradle options.
        testLogging {
            events "passed", "skipped", "failed", "standardOut", "standardError"
            outputs.upToDateWhen { false }
            showStandardStreams = true
        }
    }
    unitTests.includeAndroidResources = true

}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')

androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion", {
    exclude group: 'com.android.support', module: 'support-annotations'
})
// Espresso UI Testing dependencies
implementation "androidx.test.espresso:espresso-idling-resource:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"

testImplementation 'androidx.test:core:1.0.0'

// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.0'
// Espresso Assertions
androidTestImplementation 'androidx.test.ext:junit:1.0.0'
androidTestImplementation 'androidx.test.ext:truth:1.0.0'
androidTestImplementation 'com.google.truth:truth:0.42'
    implementation 'androidx.multidex:multidex:2.0.0'
}

My espresso_version is espressoVersion = '3.1.0'

My test that is located in module-name/src/test/java/ looks like this:

    import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.instacart.library.truetime.TrueTime
import edu.mira.aula.shared.extensions.android.trueDateNow
import edu.mira.aula.shared.network.ConnectivityHelper
import kotlinx.coroutines.experimental.runBlocking
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import java.util.*
import java.util.concurrent.CountDownLatch

class TimeExtensionsUnitTest {
private lateinit var instrumentationCtx: Context

@Before
fun setup() {
    instrumentationCtx = ApplicationProvider.getApplicationContext<Context>()
}
 @Test
fun testTrueTimeValueReturnsIfInitialized() {
    if (ConnectivityHelper.isOnline(instrumentationCtx)) {
        runBlocking {
            val countDownLatch = CountDownLatch(1)
            TrueTime.build()
                    .withSharedPreferencesCache(instrumentationCtx)
                    .withConnectionTimeout(10000)
                    .initialize()
            countDownLatch.countDown()

            try {
                countDownLatch.await()
                val dateFromTrueTime = trueDateNow()
                val normalDate = Date()
                Assert.assertNotEquals(dateFromTrueTime, normalDate)
            } catch (e: InterruptedException) {
            }
        }
    }
}

Everytime I run it, it gives me:

java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
 at androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
  at androidx.test.core.app.ApplicationProvider.getApplicationContext(ApplicationProvider.java:41)

If I run it as a Instrumental Test(changing the package) it runs without errors. But I thought that this guide was exactly to be able to run unit test using Android Framework classes such as Context. I even tried run that class UnitTestSample but the same error occurs.

I also removed all android.support dependencies from my project

Any ideas on how to solve it?


Update

You should no longer encounter this error if youre using the latest gradle version.


I also encountered this issue.

If you look at migrating to Robolectric 4.0 here, it suggest to add the following line in your gradle.properties.

android.enableUnitTestBinaryResources=true

The problem is that, if you add this you your gradle.properties, it will output this warning:

WARNING: The option setting 'android.enableUnitTestBinaryResources=true' is experimental and unsupported.

Now, if you look at Robolectric releases here. You could see that this is a known issue where they state that

Android Gradle Plugin may report the following warning, which may be safely ignored: WARNING: The option setting 'android.enableUnitTestBinaryResources=true' is experimental and unsupported.. Android Gradle Plugin 3.4 will resolve this issue.

I believe unless you could update you gradle to 3.4. You won't be able to solve this issue.

What I did instead was to include Robolectric 4.0 as dependency.

testImplementation "org.robolectric:robolectric:4.0.2"

and annotate my test class with

@RunWith(RobolectricTestRunner::class)

This should make your test work.

Now when you run the test, you'll notice that Robolectric will log the following:

[Robolectric] NOTICE: legacy resources mode is deprecated; see http://robolectric.org/migrating/#migrating-to-40

Ignore this for now but as soon as you could update your gradle, migrate to the new Robolectric testing.


I follow the official guide also met this issue, fix it with below steps.

Add testImplementation in app build.gradle

// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.13.1'

testImplementation 'androidx.test:core-ktx:1.3.0'
testImplementation 'androidx.test.ext:junit-ktx:1.1.2'

// Robolectric environment
testImplementation 'org.robolectric:robolectric:4.4'

// Optional -- truth
testImplementation 'androidx.test.ext:truth:1.3.0'
testImplementation 'com.google.truth:truth:1.0'

// Optional -- Mockito framework
testImplementation 'org.mockito:mockito-core:3.3.3'

The official guide missed two testImplementations

testImplementation 'androidx.test.ext:junit-ktx:1.1.2'

testImplementation 'org.robolectric:robolectric:4.4'

Add testOptions block in app build.gradle

 android {
        // ...
        testOptions {
            unitTests.includeAndroidResources = true
        }
    }

Add @RunWith(AndroidJUnit4::class) to your test class

Example:

import android.content.Context
import android.os.Build.VERSION_CODES.Q
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config

@RunWith(AndroidJUnit4::class)
@Config(sdk = [Q])
class UnitTestWithContextDemoTest {

    private val context: Context = ApplicationProvider.getApplicationContext()
    
    fun test_getPackageName() {
        assertThat(context.packageName).contains("your_package_name")
    }
}

NOTE

@Config(sdk = [Q]) is required when your targetSdkVersion greater than 29. Because robolectric NOT support targetSdkVersion greater than 29.


Spend hours on similar issue, and the problem wasn't in dependencies, rather in AndroidStudio itself Based on the answer:

IDE tries to run local unit tests instead of instrumented

Local tests icon.

Make sure it's run as instrumented test (red is local tests, green - instrumented):

Instrumented tests icon

After added instrumented test for the class it's run as expected under instrumented. How I done this? 2 ways I found:

1) Edit configuration (as on the last screenshot) and adding function manually

2) Under Project tap (top left corner) I selected Tests instead of android, found the test, right click - create test. After this step all new tests are run under instrumented tests