Выполнение простых тестов JUnit в Android Studio (IntelliJ) при использовании конфигурации на основе Gradle
Я использую Android Studio/IntelliJ
основываться на существующем Android
проект и хотел бы добавить несколько простых JUnit
модульные тесты. Какая папка подходит для добавления таких тестов?
Андроид Gradle
Плагин определяет структуру каталогов с src/main/java
для основного исходного кода и src/instrumentTest/java
за Android
тесты.
Попытка добавить мои тесты JUnit в instrumentTest не сработала для меня. Я могу запустить его как Android
тест (это то, что этот каталог кажется), но это не то, что я ищу - я просто хочу запустить простой JUnit
тестовое задание. Я попытался создать конфигурацию запуска JUnit для этого класса, но это также не сработало - я полагаю, потому что я использую каталог, помеченный как Android
Тест вместо источника.
Если я создам новую исходную папку и помечу ее как таковую в структуре проекта, это будет уничтожено в следующий раз IntelliJ
обновляет конфигурацию проекта из файлов сборки Gradle.
Что является более подходящим способом настройки тестов JUnit в основанном на Gradle проекте Android на IntelliJ
? Какую структуру каталогов использовать для этого?
6 ответов
Начиная с Android Studio 1.1, ответ теперь прост: http://tools.android.com/tech-docs/unit-testing-support
Обычно вы не можете. Добро пожаловать в мир Android, где все тесты должны выполняться на устройстве (кроме Robolectric).
Основная причина в том, что на самом деле у вас нет исходных текстов фреймворка - даже если вы убедите IDE выполнить тест локально, вы сразу получите исключение "Stub! Не реализовано".
"Зачем?" Вы можете спросить? Поскольку android.jar
что SDK дает вам, на самом деле все заглушено - все классы и методы есть, но все они просто выдают исключение. Он здесь для того, чтобы предоставить API, но не для того, чтобы дать вам реальную реализацию.
Есть замечательный проект под названием http://robolectric.org/, который реализует множество фреймворков просто для того, чтобы вы могли запускать содержательные тесты. В сочетании с хорошей имитацией фреймворка (например, Mockito) он делает вашу работу управляемой.
Плагин Gradle: https://github.com/robolectric/robolectric-gradle-plugin
вступление
Обратите внимание, что на момент написания Robolectric 2.4 является последней версией и не поддерживает appcompat v7
библиотека. Поддержка будет добавлена в выпуске robolectric 3.0 (пока нет ETA). Также ActionBar Sherlock
может вызвать проблемы с робототехникой.
Чтобы использовать Robolectric в Android Studio, у вас есть 2 варианта:
(Вариант 1) - Запуск тестов JUnit в Android Studio с использованием модуля Java
Этот метод использует Java-модуль для всех ваших тестов с зависимостью от вашего Android-модуля и пользовательский тестовый прогон с некоторой магией:
Инструкции можно найти здесь: http://blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-android-studio/
Также проверьте ссылку в конце этого поста для запуска тестов от Android Studio.
(Вариант 2) - Запуск тестов JUnit с Android Studio с использованием robolectric-gradle-plugin
Я столкнулся с несколькими проблемами при настройке тестов junit для запуска из gradle в Android Studio.
Это очень простой пример проекта для запуска тестов junit из основанного на gradle проекта в Android Studio: https://github.com/hanscappelle/android-studio-junit-robolectric Этот тест был протестирован с Android Studio 0.8.14, JUnit 4.10, плагин robolectric gradle 0.13+ и robolectric 2.3
Buildscript (проект /build.gradle)
Сценарий сборки - это файл build.gradle в корневом каталоге вашего проекта. Там я должен был добавить плагин robolectric gradle в classpath
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.13.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'org.robolectric:robolectric-gradle-plugin:0.13.+'
}
}
allprojects {
repositories {
jcenter()
}
}
Скрипт проекта проекта (App/build.gradle)
В сценарии сборки вашего модуля приложения используйте robolectric
плагин, добавить robolectric
Конфиг и добавить androidTestCompile
зависимостей.
apply plugin: 'com.android.application'
apply plugin: 'robolectric'
android {
// like any other project
}
robolectric {
// configure the set of classes for JUnit tests
include '**/*Test.class'
exclude '**/espresso/**/*.class'
// configure max heap size of the test JVM
maxHeapSize = '2048m'
// configure the test JVM arguments
jvmArgs '-XX:MaxPermSize=512m', '-XX:-UseSplitVerifier'
// configure whether failing tests should fail the build
ignoreFailures true
// use afterTest to listen to the test execution results
afterTest { descriptor, result ->
println "Executing test for {$descriptor.name} with result: ${result.resultType}"
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
}
Создать тестовые классы JUnit
Теперь поместите тестовые классы в расположение по умолчанию (или обновите конфигурацию Gradle)
app/src/androidTest/java
И назовите ваши тестовые классы, заканчивающиеся на Test (или снова обновите config), расширяя junit.framework.TestCase
и аннотировать методы испытаний с @Test
,
package be.hcpl.android.mytestedapplication;
import junit.framework.TestCase;
import org.junit.Test;
public class MainActivityTest extends TestCase {
@Test
public void testThatSucceeds(){
// all OK
assert true;
}
@Test
public void testThatFails(){
// all NOK
assert false;
}
}
Выполнить тесты
Затем выполните тесты, используя gradlew из командной строки (сделайте его исполняемым, используя chmod +x
если нужно)
./gradlew clean test
Образец вывода:
Executing test for {testThatSucceeds} with result: SUCCESS
Executing test for {testThatFails} with result: FAILURE
android.hcpl.be.mytestedapplication.MainActivityTest > testThatFails FAILED
java.lang.AssertionError at MainActivityTest.java:21
2 tests completed, 1 failed
There were failing tests. See the report at: file:///Users/hcpl/Development/git/MyTestedApplication/app/build/test-report/debug/index.html
:app:test
BUILD SUCCESSFUL
Поиск проблемы
каталоги альтернативных источников
Точно так же, как вы можете иметь свои исходные файлы java где-то еще, вы можете перемещать свои тестовые исходные файлы. Просто обновите Gradle sourceSets
конфигурации.
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
androidTest {
setRoot('tests')
}
}
пакет org.junit не существует
Вы забыли добавить зависимость теста junit в скрипт сборки приложения
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
}
java.lang.RuntimeException: заглушка!
Вы запускаете этот тест с конфигурациями запуска из Android Studio вместо командной строки (вкладка "Терминал" в Android Studio). Чтобы запустить его из Android Studio, вам необходимо обновить app.iml
файл, в котором внизу должна быть запись jdk. Смотрите пример deckard-gradle для подробностей.
Полный пример ошибки:
!!! JUnit version 3.8 or later expected:
java.lang.RuntimeException: Stub!
at junit.runner.BaseTestRunner.<init>(BaseTestRunner.java:5)
at junit.textui.TestRunner.<init>(TestRunner.java:54)
at junit.textui.TestRunner.<init>(TestRunner.java:48)
at junit.textui.TestRunner.<init>(TestRunner.java:41)
at com.intellij.rt.execution.junit.JUnitStarter.junitVersionChecks(JUnitStarter.java:190)
at com.intellij.rt.execution.junit.JUnitStarter.canWorkWithJUnitVersion(JUnitStarter.java:173)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
ОШИБКА: для JAVA_HOME задан неверный каталог
Посмотрите этот ТАК вопрос для решения. Добавьте приведенный ниже экспорт в ваш профиль bash:
export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
Полный журнал ошибок:
ERROR: JAVA_HOME is set to an invalid directory: export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.
Тестовый класс не найден
Если вы хотите запускать свои тесты из Android Studio Junit Test Runner, вместо этого вам придется немного расширить файл build.gradle, чтобы android studio могла найти ваши скомпилированные тестовые классы:
sourceSets {
testLocal {
java.srcDir file('src/test/java')
resources.srcDir file('src/test/resources')
}
}
android {
// tell Android studio that the instrumentTest source set is located in the unit test source set
sourceSets {
instrumentTest.setRoot('src/test')
}
}
dependencies {
// Dependencies for the `testLocal` task, make sure to list all your global dependencies here as well
testLocalCompile 'junit:junit:4.11'
testLocalCompile 'com.google.android:android:4.1.1.4'
testLocalCompile 'org.robolectric:robolectric:2.3'
// Android Studio doesn't recognize the `testLocal` task, so we define the same dependencies as above for instrumentTest
// which is Android Studio's test task
androidTestCompile 'junit:junit:4.11'
androidTestCompile 'com.google.android:android:4.1.1.4'
androidTestCompile 'org.robolectric:robolectric:2.3'
}
task localTest(type: Test, dependsOn: assemble) {
testClassesDir = sourceSets.testLocal.output.classesDir
android.sourceSets.main.java.srcDirs.each { dir ->
def buildDir = dir.getAbsolutePath().split('/')
buildDir = (buildDir[0..(buildDir.length - 4)] + ['build', 'classes', 'debug']).join('/')
sourceSets.testLocal.compileClasspath += files(buildDir)
sourceSets.testLocal.runtimeClasspath += files(buildDir)
}
classpath = sourceSets.testLocal.runtimeClasspath
}
check.dependsOn localTest
от: http://kostyay.name/android-studio-robolectric-gradle-getting-work/
Еще немного ресурсов
Лучшие статьи, которые я нашел вокруг этого:
Теперь это поддерживается в Android Studio, начиная с плагина Android Gradle 1.1.0, проверьте это:
https://developer.android.com/training/testing/unit-testing/local-unit-tests.html
Пример приложения с локальными модульными тестами на GitHub:
https://github.com/googlesamples/android-testing/tree/master/unittesting/BasicSample
Для Android Studio 1.2+ настроить проект для JUnit довольно просто, попробуйте следовать этому уроку:
Это самая простая часть настройки проекта для JUnit:
https://io2015codelabs.appspot.com/codelabs/android-studio-testing
Следуйте по прошедшей ссылке до тех пор, пока не пройдете " Проведение тестов "
Теперь, если вы хотите интегрироваться с тестом Intrumentation, следуйте инструкциям здесь:
https://io2015codelabs.appspot.com/codelabs/android-studio-testing
Пожалуйста, ознакомьтесь с этим руководством с официального сайта разработчиков Android. В этой статье также показано, как создавать макеты для тестирования.
Кстати, вы должны заметить, что область зависимостей для простого теста JUnit должна быть "testCompile".