Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.Exception: Custom runner class AndroidJUnit4 should have a public constructor with signature AndroidJUnit4(Class testClass)

gradle looks like:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        applicationId "com.google.developer.taskmaker"
        minSdkVersion 19
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

configurations.all {
    resolutionStrategy {
        force 'com.android.support:support-annotations:25.2.0'
    }
}


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support:recyclerview-v7:25.2.0'
    compile 'com.android.support:design:25.2.0'
    compile 'com.android.support:preference-v7:25.2.0'
    debugCompile 'im.dino:dbinspector:3.4.1@aar'
    // Android JUnit Runner
    compile 'com.google.android.gms:play-services-appindexing:8.4.0'
    // Android runner and rules support

    // add this for intent mocking support
    androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'

    // add this for webview testing support
    androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2'
    compile 'com.android.support.test:runner:0.5'
    compile 'com.android.support.test:rules:0.5'
    compile 'com.android.support.test.espresso:espresso-core:2.2.2'
}

Unit test case looks like

@RunWith(AndroidJUnit4.class)
public class TestClass {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule =
            new ActivityTestRule<>(MainActivity.class);

    @Test
    public void buttonClick(){
        onView(withId(R.id.fab)).perform(click()).check(matches(isDisplayed()));
    }

}

Error message looks like:

java.lang.Exception: Custom runner class AndroidJUnit4 should have a public constructor with signature AndroidJUnit4(Class testClass)

    at org.junit.runners.model.InitializationError.<init>(InitializationError.java:38)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:111)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:101)
    at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:87)
    at com.intellij.junit4.JUnit46ClassesRequestBuilder.collectWrappedRunners(JUnit46ClassesRequestBuilder.java:90)
    at com.intellij.junit4.JUnit46ClassesRequestBuilder.getClassesRequest(JUnit46ClassesRequestBuilder.java:51)
    at com.intellij.junit4.JUnit4TestRunnerUtil.buildRequest(JUnit4TestRunnerUtil.java:91)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:95)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)


Process finished with exit code -1

I have already check other answers but not getting solution.Please tell where thing goes wrong. When running this code I am getting error

like image 540
Aman Srivastava Avatar asked Apr 02 '17 17:04

Aman Srivastava


2 Answers

Cause 1: placing tests in the wrong folder

This error can be replicated by making a new Application with the default template in Android Studio and copying the auto-generated ExampleInstrumentedTest from the androidTest folder to the test folder:

incorrectly copying an instrumented test into the test folder

Here's what the error looks like:

the OPs error java.lang.Exception: Custom runner class AndroidJUnit4 should have a public constructor with signature AndroidJUnit4(Class testClass)

Note that in order to replicate the problem you would also have to incorrectly add dependencies to the module-level build.gradle:

dependencies in the wrong place

Cause 2: wrong test configuration

Local unit tests and instrumented tests have different Run configurations. If you click Edit Configurations like below:

test configuration

You should see your instrumented tests under Android Instrumented Tests and your local unit tests under the Android JUnit like in the illustrations below:

For Android Instrumented Tests the config should look something like below:

test config for Android Instrumented tests

For Android JUnit:

test config for Android JUnit tests

When you run a test, Android Studio will create a run config for you. If the run config is in the wrong category, check you have your test and androidTest folders correct and then you can delete the run config from the Edit configurations and run the test again. If you have set up correctly, Android Studio will use the correct type of run configuration this time.

Explanation

There are two types of tests in Android:

  1. Instrumented tests
  2. Local unit tests

Instrumented tests

Instrumented tests are tests that are designed to run on a handset or emulator. These are tests where you need access to a fully-functional part of the Android library (like a real Context for example). These need to go in the androidTest folder and dependencies for these tests (e.g., Espresso, com.android.support.test.rules:0.5) will be prefixed with androidTestCompile in your build.gradle.

Here is an example instrumented test:

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

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

import static org.junit.Assert.assertEquals;

/**
 * Instrumentation test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.gyaltsab.myapplication", appContext.getPackageName());
    }
}

Local unit tests

Local unit tests are tests that you can run in your IDE. They normally don't depend on any part of the Android library not available on a standard JVM (e.g., they won't depend on Context). The dependencies for these go in the testCompile part of your build.gradle.

Here is an example unit test:

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

Note that local unit tests do not need the @RunWith(AndroidJUnit4.class) annotation in the class declaration. Please see the official docs for a more complete explanation.

like image 186
David Rawson Avatar answered Nov 14 '22 10:11

David Rawson


I had the same problem. I'm working in Android studio 2.3.1. I checked my run configurations. Under Run->Edit Configurations and discovered the test I was trying to run as an instrumented test was under the Android JUnit tests category, even though I had it in the androidTest directory in my project. I added an Android Instrumented Test (hit the plus button in the corner) and set it to point to the test I was trying to run. That fixed it for me.

like image 8
no1isnothing Avatar answered Nov 14 '22 09:11

no1isnothing