Java.lang.Exception: Пользовательский класс runner AndroidJUnit4 должен иметь открытый конструктор с сигнатурой AndroidJUnit4 (класс testClass)
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:[email protected]'
// 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 выглядит как
@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
Я уже проверял другие ответы, но не получал решение. Пожалуйста, расскажите, где все пойдет не так. При запуске этого кода я получаю сообщение об ошибке
Ответы
Ответ 1
Причина 1: размещение тестов в неправильной папке
Эта ошибка может быть реплицирована путем создания нового приложения с шаблоном по умолчанию в Android Studio и копирования автоматически сгенерированного ExampleInstrumentedTest
из androidTest
в папку test
:
![неправильное копирование инструментального теста в тестовую папку]()
Вот как выглядит ошибка:
![ошибка OPs java.lang.Exception: пользовательский класс runner AndroidJUnit4 должен иметь открытый конструктор с сигнатурой AndroidJUnit4 (класс testClass)]()
Обратите внимание, что для репликации проблемы вам также придется неправильно добавлять зависимости на уровне модуля build.gradle
:
![зависимости в неправильном месте]()
Причина 2: неправильная конфигурация теста
Локальные модульные тесты и инструментальные тесты имеют разные конфигурации запуска. Если вы нажмете "Изменить конфигурации", как показано ниже:
![тестовая конфигурация]()
Вы должны увидеть свои контрольные тесты в разделе Android Instrumented Tests
, а ваши локальные модули тестируются под Android JUnit
, как показано на рисунках ниже:
Для Android Instrumented Tests конфигурация должна выглядеть примерно так:
![test config для Android Instrumented tests]()
Для Android JUnit:
![тестовая конфигурация для тестов Android JUnit]()
Когда вы запустите тест, Android Studio создаст для вас конфигурацию прогона. Если конфигурация прогона находится в неправильной категории, убедитесь, что у вас есть папки test
и androidTest
, и вы можете удалить конфигурацию прогона из Edit configurations
и снова запустить тест. Если вы правильно настроили, на этот раз Android Studio будет использовать правильный тип конфигурации запуска.
Объяснение
В Android есть два типа тестов:
- Тестируемые тесты
- Локальные тесты
Контрольные тесты
Тестируемые тесты - это тесты, которые предназначены для работы на эмуляторе телефона или . Это те тесты, где вам необходим доступ к полнофункциональной части библиотеки 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. Обычно они не зависят от какой-либо части библиотеки Android, недоступной на стандартной JVM (например, они не будут зависеть от Context
). Зависимости для них идут в testCompile
части вашего build.gradle
.
Вот пример 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);
}
}
Обратите внимание, что тесты локального блока не нуждаются в аннотации @RunWith(AndroidJUnit4.class)
в объявлении класса. Для более полного объяснения см. официальные документы.
Ответ 2
У меня была та же проблема. Я работаю в студии Android 2.3.1. Я проверил свои настройки запуска. В разделе Run- > Edit Configurations и обнаруженный тест, который я пытался запустить в качестве инструментального теста, был включен в категорию тестов Android JUnit, хотя я использовал его в каталоге androidTest в моем проекте. Я добавил Android Instrumented Test (нажмите кнопку "плюс" в углу) и установил, чтобы он указывал на тест, который я пытался запустить. Это исправило это для меня.
Ответ 3
Попробуйте переместить тестовый файл в папку androidTest.