27

I try to run Kotlin instrumentation tests for android.

In my app/build.gradle:

    android {
        dataBinding {
            enabled = true
        }
        compileSdkVersion 28
        defaultConfig {
            applicationId "com.myproject"
            minSdkVersion 18
            targetSdkVersion 28
            versionCode 6
            versionName "0.0.7"
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }

        sourceSets {
            main.java.srcDirs += 'src/main/kotlin'
            androidTest.java.srcDirs += 'src/androidTest/kotlin'
        }

androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test:rules:1.1.2-alpha02'
    androidTestImplementation 'androidx.test:runner:1.1.2-alpha02'

In folder /app/src/androidTest/kotlin/com/myproject/ I has Kotlin test:

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Rule
import org.junit.runner.RunWith

import androidx.test.rule.ActivityTestRule
import com.myproject.ui.activity.TradersActivity
import org.junit.Before


@RunWith(AndroidJUnit4::class)
@SmallTest
class TradersActivityTest {

    private lateinit var stringToBetyped: String

    @get:Rule
    var activityRule: ActivityTestRule<TradersActivity> = ActivityTestRule(TradersActivity::class.java)

    @Before
    fun initValidString() {
        // Specify a valid string.
        stringToBetyped = "Espresso"
    }

}

but when I run test I get error:

$ adb shell am instrument -w -r   -e debug false -e class 'com.myproject.TradersActivityTest' com.myproject.debug.test/androidx.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests

java.lang.RuntimeException: Delegate runner 'androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner' for AndroidJUnit4 could not be loaded.
at androidx.test.ext.junit.runners.AndroidJUnit4.throwInitializationError(AndroidJUnit4.java:92)
at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:82)
at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:51)
at androidx.test.ext.junit.runners.AndroidJUnit4.<init>(AndroidJUnit4.java:46)
at java.lang.reflect.Constructor.newInstance(Native Method)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at androidx.test.internal.runner.junit4.AndroidAnnotatedBuilder.runnerForClass(AndroidAnnotatedBuilder.java:63)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at androidx.test.internal.runner.AndroidRunnerBuilder.runnerForClass(AndroidRunnerBuilder.java:153)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at androidx.test.internal.runner.TestLoader.doCreateRunner(TestLoader.java:73)
at androidx.test.internal.runner.TestLoader.getRunnersFor(TestLoader.java:104)
at androidx.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:789)
at androidx.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:544)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:387)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:72)
... 16 more
Caused by: org.junit.runners.model.InitializationError
at org.junit.runners.ParentRunner.validate(ParentRunner.java:418)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:84)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.java:43)
at androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner.<init>(AndroidJUnit4ClassRunner.java:48)
... 18 more

Tests ran to completion.
2
  • Did you manage to solve it? Commented May 21, 2019 at 9:15
  • 1
    @saiedmomen this help: atRule atJvmField var tradersIntentTestRule = IntentsTestRule(TradersActivity::class.java, false, false) Commented May 21, 2019 at 10:12

11 Answers 11

21

I faced this problem in kotlin , used below code and it worked

@RunWith(AndroidJUnit4::class)

@LargeTest

class MainActivityTest {

    private val TAG = "MainActivityTest"

    @get:Rule
    val activityRule = ActivityTestRule(MainActivity::class.java)
}

follow the link below:- https://developer.android.com/training/testing/junit-rules

Sign up to request clarification or add additional context in comments.

1 Comment

Changing @Rule to ``@get:Rule` resolved the issue for me.
11

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

You can try to put a @Test method and run

@Test
public void signInTest() {


}

3 Comments

that was my problem
This answer does not make any sense. When you remove the test method, then there are no more tests to run, therefore it works. But that's not the point.
@AlexanderPacha You've got it backwards -- they're saying that you need to add a test method to get it to work. This was, in fact, my silly little problem. I forgot to annotate my methods with @Test. You'll see this error if you have no @Test-annotated methods.
8

For those who still have problems like this, This happens because Kotlin compiler wants to generate getter/setter properties. for example, I've got this error because I didn't mention @Rule annotation with @get:Rule.

If we annotate properties like this with @get:... or @JvmField it could solve the problem.

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

Or

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

@JvmField instructs the Kotlin compiler not to generate getters/setters for this property and expose it as a field.

1 Comment

this did it for me
7

In regards to @RunWith(AndroidJUnit4::class)

Delete

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

Use

import androidx.test.runner.AndroidJUnit4

3 Comments

Did not work for me. Also, the androidx.test.runner.AndroidJUnit4 is deprecated. Source: developer.android.com/reference/androidx/test/runner/…
It wasn't depreciated at the time of writing, but thanks for your comment. Others, please find an ALTERNATIVE workaround as this is depreciated. Thanks to Luciano for finding out.
The import you suggest is giving "Unresolved reference: AndroidJUnit4"
2

I got this error when I have some parameters in my test method. So, if you have it - delete it.

@Test
fun someTestMethod(someParams: Int) { // delete method params
    assert(1==1)
}

1 Comment

This was it for me - more generally, if the signature of a test was incorrect I received this error. I bumped into this testing coroutines where I omitted the <Unit> on the example below. fun testSuspendFunction() = runBlocking<Unit> {}
2

just make sure that if your test is calling any suspend methods, you run your test with runBlocking{}. Solved the problem for me

Comments

2

Max Kilzieh answer worked for me Using import androidx.test.runner.AndroidJUnit4 instead of import androidx.test.ext.junit.runners.AndroidJUnit4

Comments

2

I just wasted all day on this issue 😵

I'm guessing you are using the multiplatform plugin like I am.

I was about to give up on trying to moving my instrumented tests to src/androidTest/kotlin instead of src/androidTest/java

when I decided to log kotlin.sourcesets.names, which printed

[androidAndroidTest, androidAndroidTestDebug, androidDebug, androidMain, androidRelease, androidTest, androidTestDebug, androidTestRelease, commonMain, commonTest, iosArm32Main, iosArm32Test, iosArm64Main, iosArm64Test, iosX64Main, iosX64Test, macosX64Main, macosX64Test]

Soo I realized in order for dependencies to resolve correctly I needed to change

androidTestImplementation -> androidAndroidTestImplementation
testImplementation -> androidTestImplementation

They don't describe this in the documentation of course. (as far as I have found)

... so for example, for you, I think the dependencies for your instrumented test dependencies should be:

androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02'

not

androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha02'

Comments

1

You don't have any functions annotated with @Test. This is likely the cause of the issue. I've run my own test using the AndroidJUnit4 runner on a class without @Test functions, and reconstructed this behavior.

The AndroidJUnit4 JUnit4 runner is the cause of this issue, and despite its attempt to provide a detailed message (see the code where the exception is thrown), it gives you a wrong message.

The following are more ways to achieve this error:

@Test
fun willThrowInitializationErrorBecauseReturnsNonUnitValue(): Int {
    return 0
}

@Test
fun willThrowInitializationErrorBecauseTakesParameters(param: Int) {
}

The error is generated by the fact that you're writing JUnit4 style tests, and they're expected to conform to JUnit4 semantics, but it would be nice if the error message were more clear.

To make matters worse, if one test function is messed up the runner won't run any tests because the InitializationError is thrown in the constructor of the AndroidJUnit4 class.

Comments

0

In My case while using Java,I faced issue when I did below mistakes.

1)I had made ActivityTestRule as private.

  All test cases should be public always.

2)I didn't add static for BeforeClass and AfterClass methods

  Methods of @BeforeClass and @AfterClass should be static

  Ex)@BeforeClass
     public static void setUp(){

     }

Comments

0

Also just to expand on the answers, but it won't help for this particular reason:

If you use kotlin and get this while testing, make sure you aren't using suspend in DAO.

(Sorry to put it here, there was no thread with this in kotlin and I already found the solution so it might help someone)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.