Ответ 1
Начиная с Android Studio 1.1, ответ прост: http://tools.android.com/tech-docs/unit-testing-support
Я использую Android Studio/IntelliJ
для создания существующего проекта Android
и хотел бы добавить несколько простых тегов JUnit
. Какая правильная папка для добавления таких тестов?
Плагин android Gradle
определяет структуру каталогов с src/main/java
для основного исходного кода и src/instrumentTest/java
для Android
.
Попытка добавить мои тесты JUnit в instrumentTest не помогла мне. Я могу запустить его как тест Android
(для чего это каталог), но это не то, что я ищу - я просто хочу запустить простой тест JUnit
.
Я попытался создать конфигурацию запуска JUnit для этого класса, но это также не сработало - я полагаю, потому что я использую каталог, помеченный как Android
Test вместо Source.
Если я создаю новую исходную папку и помечаю ее как таковой в структуре проекта, это будет очищено в следующий раз IntelliJ
обновляет конфигурацию проекта из файлов сборки gradle.
Каков наиболее подходящий способ настройки тестов JUnit в проекте Android на gradle на IntelliJ
? Какую структуру каталогов использовать для этого?
Начиная с Android Studio 1.1, ответ прост: http://tools.android.com/tech-docs/unit-testing-support
Обычно вы не можете. Добро пожаловать в мир Android, где все тесты должны выполняться на устройстве (кроме Robolectric).
Основная причина заключается в том, что на самом деле у вас нет источников фреймворка - даже если вы убедите среду IDE выполнить тест локально, вы сразу же получите исключение "Stub! Not Implement".
"Зачем?" вы можете задаться вопросом? Поскольку android.jar
, который дает вам SDK, на самом деле все вычеркнуто - все классы и методы есть, но все они просто бросают исключение. Это там, чтобы предоставить API, но не там, чтобы дать вам реальную реализацию.
Там замечательный проект под названием Robolectric, который реализует многие рамки только для того, чтобы вы могли запускать осмысленные тесты. В сочетании с хорошей макетной каркасной структурой (например, Mockito) она делает вашу работу управляемой.
Gradle плагин: https://github.com/robolectric/robolectric-gradle-plugin
Обратите внимание, что на момент написания robolectric 2.4 является последней версией и не поддерживает библиотеку appcompat v7
. Поддержка будет добавлена в релиз robolectric 3.0 (пока еще нет ETA). Также ActionBar Sherlock
может вызвать проблемы с robolectric.
Чтобы использовать Robolectric в Android Studio, у вас есть 2 варианта:
Этот метод использует java-модуль для всех ваших тестов с зависимостью вашего модуля android и пользовательского тестового бегуна с некоторой магией:
Инструкции можно найти здесь: http://blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-android-studio/
Также проверьте ссылку в конце этого сообщения для запуска тестов из студии android.
У меня возникли проблемы с настройкой 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
Строка script - это файл 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()
}
}
В сборке script вашего модуля приложения используйте плагин 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'
}
Теперь поместите тестовые классы в папку по умолчанию (или обновите gradle config)
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')
}
}
Вы забыли добавить зависимость теста junit в приложении build script
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
}
Вы используете этот тест с настройками запуска из 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)
См. этот вопрос SO для решения. Добавьте ниже представленный вам профиль 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, вам придется немного расширить файл build.gradle, чтобы студия Android могла находить ваши скомпилированные тестовые классы:
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 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
from: http://kostyay.name/android-studio-robolectric-gradle-getting-work/
Лучшие статьи, которые я нашел по этому поводу:
Теперь это поддерживается в Android Studio, начиная с Android Gradle plugin 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#1
Следуйте по предыдущей ссылке до тех пор, пока Запуск тестов
Теперь, если вы хотите интегрироваться с тестом интрументации, следуйте отсюда:
https://io2015codelabs.appspot.com/codelabs/android-studio-testing#6
Пожалуйста, ознакомьтесь с этим учебник на официальном сайте разработчиков Android. В этой статье также показано, как создавать макеты для вашего тестирования.
Кстати, вы должны заметить, что область зависимостей для простого теста JUnit должна быть "testCompile".