Migrating Junit4 tests to androidx: What causes 'delegate runner could not be loaded'?

29,049

Solution 1

Removing @RunWith(AndroidJUnit4.class) annotations from the test classes fixed the issue, although I can't really say why or how it fixed it.

Edit: Allright I did some more testing. I migrated my app to Kotlin, and suddenly I noticed the tests began to work with the @RunWith annotation, too. Here's what I found out:

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import androidx.test.ext.junit.runners.AndroidJUnit4;

@RunWith(AndroidJUnit4.class) // <-- @RunWith + @BeforeClass = Error
public class AndroidXJunitTestJava {

    @BeforeClass
    public static void setup() {
        // Setting up once before all tests
    }

    @Test
    public void testing() {
        // Testing....
    }
}

This java test fails with the Delegate runner for AndroidJunit4 could not be loaded error. But If I remove the @RunWith annotation, it works. Also, if I replace the @BeforeClass setup with just a @Before, like this:

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import androidx.test.ext.junit.runners.AndroidJUnit4;

@RunWith(AndroidJUnit4.class) // <-- @RunWith + @Before = works?
public class AndroidXJunitTestJava {

    @Before
    public void setup() {
        // Setting up before every test
    }

    @Test
    public void testing() {
        // Testing....
    }
}

The tests will run without errors. I needed to use the @BeforeClass annotation, so I just removed @RunWith.

But now that I am using Kotlin, the following (which should be equal to the first java example) works:

import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class AndroidXJunitTest {

    companion object {
        @BeforeClass fun setup() {
            // Setting up
        }
    }

    @Test
    fun testing() {
        // Testing...
    }

}

Also, as Alessandro Biessek said in an answer and @Ioane Sharvadze in the comments, the same error can happen with the @Rule annotation. If I add a line

 @Rule val instantTaskExecutorRule = InstantTaskExecutorRule()

To the Kotlin example, the same delegate runner error happens. This must be replaced with

@get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule()

Explanation here.

Solution 2

You also get the error message if you use a test rule in Kotlin and write it Java style

@Rule
var mainActivityActivityTestRule = ActivityTestRule(MainActivity::class.java)

You have to change @Rule to @get:Rule

@get:Rule
var mainActivityActivityTestRule = ActivityTestRule(MainActivity::class.java) 

Solution 3

The error message displayed when I delete the @Test method.

You can try to put a @Test method and run

@Test
public void signInTest() {


}

Solution 4

While testing for activity make sure ActivityTestRule variable is public :

@Rule
public ActivityTestRule<YourActivity> activityTestRule = new ActivityTestRule<>(YourActivity.class); 

Solution 5

There are 2 ways that you can try to resolve this problem:

Solution 1:

Build --> Clean Project. Then Build --> Rebuild Project

Solution 2:

There are 2 packages that has of AndroidJUnit4

  1. androidx.test.runner (deprecated)
  2. androidx.test.ext.junit.runners

Make sure your build.gradle (app) has this line

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

and make sure you use (1) (which is deprecated) instead of (2) (new but not stable yet) in @RunWith(AndroidJUnit4.class) before your test class.

Share:
29,049
J. Nuutinen
Author by

J. Nuutinen

Updated on July 08, 2022

Comments

  • J. Nuutinen
    J. Nuutinen almost 2 years

    I am migrating my app to androidx, I can't seem to get my unit tests working. I took example from Google's AndroidJunitRunnerSample, which has been updated to use the new androidx api. I get the following error when trying to run my tests:

    java.lang.Exception: Delegate runner 'androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner' for AndroidJUnit4 could not be loaded. Check your build configuration.
    

    Here is my module build.gradle:

    android {
        defaultConfig {
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    }
    dependencies {
        // Test dependencies
        androidTestImplementation 'androidx.test:core:1.0.0-beta02'
        androidTestImplementation 'androidx.test.ext:junit:1.0.0-beta02'
        androidTestImplementation 'androidx.test:runner:1.1.0-beta02'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-beta02'
        androidTestImplementation "androidx.arch.core:core-testing:2.0.0"
        androidTestImplementation 'androidx.room:room-testing:2.1.0-alpha01'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-beta02'
        androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
    }
    

    And here is how my tests are structured:

    import org.junit.BeforeClass;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    
    import androidx.test.ext.junit.runners.AndroidJUnit4;
    
    @RunWith(AndroidJUnit4.class)
    public class EntityParcelTest {
    
        @BeforeClass
        public void createEntities() {
            // Setup...
        }
    
        @Test
        void someTest() {
            // Testing here
        }
    

    What am I doing wrong?