java.lang.Exception:自定义运行器类AndroidJUnit4应该有一个带有签名AndroidJUnit4的公共构造函数(Class testClass)

时间:2017-04-02 17:40:57

标签: android android-espresso

gradle看起来像:

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'
}

单元测试用例看起来像

@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()));
    }

}

错误消息如下:

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

我已经检查了其他答案但没有得到解决方案。请告诉我哪里出错了。运行此代码时出现错误

5 个答案:

答案 0 :(得分:36)

原因1:将测试放在错误的文件夹中

可以通过在Android Studio中使用默认模板创建新应用程序并将自动生成的ExampleInstrumentedTestandroidTest文件夹复制到test文件夹来复制此错误:

incorrectly copying an instrumented test into the test folder

这里的错误是什么:

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

请注意,为了复制问题,您还必须错误地将依赖项添加到模块级build.gradle

dependencies in the wrong place

原因2:测试配置错误

本地单元测试和仪表测试具有不同的运行配置。如果您点击编辑配置,如下所示:

test configuration

您应该会在Android Instrumented Tests下看到您的检测测试,并在Android JUnit下看到您的本地单元测试,如下图所示:

对于Android Instrumented Tests,配置应如下所示:

test config for Android Instrumented tests

对于Android JUnit:

test config for Android JUnit tests

当您运行测试时,Android Studio将为您创建运行配置。如果运行配置的类别错误,请检查您的testandroidTest文件夹是否正确,然后您可以从Edit configurations删除运行配置并再次运行测试。如果您已正确设置,Android Studio将使用正确类型的运行配置。

解释

Android中有两种类型的测试:

  1. 仪器化测试
  2. 本地单元测试
  3. 仪器化测试

    检测测试是旨在在手机模拟器上运行的测试。这些是您需要访问Android库的全功能部分的测试(例如真实的Context)。这些需要放在androidTest文件夹中,并且这些测试的依赖项(例如,Espresso,com.android.support.test.rules:0.5)将以androidTestCompile中的build.gradle作为前缀。

    以下是一个仪表化测试示例:

    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());
        }
    }
    

    本地单元测试

    本地单元测试是您可以在IDE中运行的测试。他们通常不依赖于标准JVM上不可用的Android库的任何部分(例如,他们不依赖于Context)。这些依赖项属于testCompile的{​​{1}}部分。

    以下是单元测试示例:

    build.gradle

    请注意,本地单元测试不需要类声明中的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); } } 注释。有关更完整的说明,请参阅the official docs

答案 1 :(得分:8)

我遇到了同样的问题。我在Android studio 2.3.1工作。我检查了我的运行配置。在Run-&gt;编辑配置下,发现了我试图运行的测试,因为一个检测测试是在Android JUnit测试类别下运行的,即使我在项目的androidTest目录中也有它。我添加了一个Android Instrumented Test(点击角落里的加号按钮)并将其设置为指向我试图运行的测试。这为我解决了。

答案 2 :(得分:3)

尝试将测试文件移动到androidTest文件夹。

答案 3 :(得分:1)

解决方案: - 您必须将测试文件夹从test更改为androidTest并编辑测试配置。(或将测试文件从testTest移动到androidTest编辑测试配置)

我在此视频中找到了解决方案:https://youtu.be/TGU0B4qRlHY?t=9m36s

并且在这里: - https://stackoverflow.com/a/30172064/5723125

答案 4 :(得分:1)

对于我来说,该问题通过以下行解决:

@RunWith(AndroidJUnit4ClassRunner.class)