Migrating Junit4 tests to androidx: What causes 'delegate runner could not be loaded'?
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
androidx.test.runner
(deprecated)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.
J. Nuutinen
Updated on July 08, 2022Comments
-
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?