Ich verwende Android Studio/IntelliJ
, um auf einem vorhandenen Android
-Projekt aufzubauen, und möchte einige einfache JUnit
-Komponententests hinzufügen. Was ist der richtige Ordner, um solche Tests hinzuzufügen?
Das Android-Plugin Gradle
definiert eine Verzeichnisstruktur mit src/main/Java
für den Hauptquellcode und src/instrumentTest/Java
für Android
-Tests.
Der Versuch, meine JUnit-Tests in instrumentTest hinzuzufügen, hat für mich nicht funktioniert. Ich kann es als Android
-Test ausführen (dafür scheint dieses Verzeichnis zu sein), aber das ist nicht das, wonach ich suche - ich möchte nur einen einfachen JUnit
-Test ..__ ausführen das hat auch nicht funktioniert - ich nehme an, ich verwende ein Verzeichnis, das als Android
Test anstelle von Source gekennzeichnet ist.
Wenn ich einen neuen Quellordner anlege und als solcher in der Projektstruktur markiere, wird dies beim nächsten Mal gelöscht, wenn IntelliJ
die Projektkonfiguration aus den Gradle-Build-Dateien aktualisiert.
Was ist der geeignetere Weg, um JUnit-Tests in einem gradbasierten Android-Projekt unter IntelliJ
zu konfigurieren? Welche Verzeichnisstruktur soll dafür verwendet werden?
Ab Android Studio 1.1 ist die Antwort jetzt einfach: http://tools.Android.com/tech-docs/unit-testing-support
Normalerweise kannst du nicht. Willkommen in der Welt von Android, wo alle Tests auf einem Gerät ausgeführt werden müssen (außer Robolectric).
Der Hauptgrund ist, dass Sie nicht wirklich über die Quellen des Frameworks verfügen. Selbst wenn Sie die IDE davon überzeugen, den Test lokal auszuführen, erhalten Sie sofort die Ausnahme "Stub! Nicht implementiert" Warum? " du fragst dich vielleicht? Da der Android.jar
, den Ihnen das SDK gibt, tatsächlich alle entfernt ist - alle Klassen und Methoden sind vorhanden, werfen jedoch nur eine Ausnahme aus. Es ist dazu da, eine API bereitzustellen, aber nicht, um Ihnen eine tatsächliche Implementierung zu geben.
Es gibt ein wunderbares Projekt namens Robolectric , das einen Großteil des Frameworks implementiert, sodass Sie aussagekräftige Tests durchführen können. In Verbindung mit einem guten Mock-Framework (z. B. Mockito) wird Ihr Job überschaubar.
Gradle Plugin: https://github.com/robolectric/robolectric-gradle-plugin
Beachten Sie, dass robolectric 2.4 zum Zeitpunkt des Schreibens die neueste Version ist und keine Unterstützung für die appcompat v7
-Bibliothek bietet. Unterstützung wird in Version 3.0 von robolectric hinzugefügt (noch keine ETA). Auch ActionBar Sherlock
kann Probleme mit Robolectric verursachen.
Um Robolectric in Android Studio verwenden zu können, haben Sie zwei Möglichkeiten:
Diese Technik verwendet ein Java-Modul für alle Ihre Tests mit einer Abhängigkeit zu Ihrem Android-Modul und einen benutzerdefinierten Testläufer mit etwas Magie:
Anweisungen finden Sie hier: http://blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-Android-studio/
Überprüfen Sie auch den Link am Ende dieses Beitrags, um die Tests von Android Studio aus durchzuführen.
Ich habe ein paar Probleme mit der Einrichtung von Junit-Tests zur Ausführung von Absolventen in Android Studio festgestellt.
Dies ist ein sehr einfaches Beispielprojekt zum Ausführen von Junit-Tests eines gradle-basierten Projekts in Android Studio: https://github.com/hanscappelle/Android-studio-junit-robolectric Dies wurde mit Android Studio 0.8.14 getestet , JUnit 4.10, robolectric gradle plugin 0.13+ und robolectric 2.3
Das Build-Skript ist die Datei build.gradle im Stammverzeichnis Ihres Projekts. Dort musste ich robolectric gradle plugin zu classpath hinzufügen
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()
}
}
Verwenden Sie im Build-Skript Ihres App-Moduls das Plugin robolectric
, fügen Sie robolectric
config hinzu und fügen Sie androidTestCompile
-Abhängigkeiten hinzu.
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'
}
Legen Sie die Testklassen jetzt in den Standardspeicherort (oder aktualisieren Sie die Gradle-Konfiguration).
app/src/androidTest/Java
Benennen Sie Ihre Testklassen mit "Test" (oder aktualisieren Sie erneut "config"), erweitern Sie junit.framework.TestCase
und kommentieren Sie Testmethoden mit "@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;
}
}
Führen Sie dann die Tests mit gradlew von der Kommandozeile aus (machen Sie sie ggf. mit chmod +x
ausführbar).
./gradlew clean test
Beispielausgabe:
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
So wie Sie Ihre Java-Quelldateien an einem anderen Ort haben können, können Sie auch Ihre Testquelldateien verschieben. Aktualisieren Sie einfach gradle sourceSets
config.
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
Java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
androidTest {
setRoot('tests')
}
}
Sie haben vergessen, die Junit-Testabhängigkeit im App-Buildskript hinzuzufügen
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
}
Sie führen diesen Test mit den Laufkonfigurationen von Android Studio anstelle der Befehlszeile aus (Registerkarte "Terminal" in Android Studio). Um es von Android Studio aus auszuführen, müssen Sie die app.iml
-Datei aktualisieren, damit der Eintrag jdk unten angezeigt wird. Siehe Deckard-Gradle-Beispiel für Details.
Vollständiges Fehlerbeispiel:
!!! 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)
Siehe diese SO Frage für eine Lösung. Fügen Sie den folgenden Export zu Ihrem Bash-Profil hinzu:
export Java_HOME=`/usr/libexec/Java_home -v 1.7`
Das vollständige Fehlerprotokoll:
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.
Wenn Sie Ihre Tests stattdessen mit Android Studio Junit Test Runner ausführen möchten, müssen Sie die build.gradle-Datei ein wenig erweitern, damit Android Studio Ihre kompilierten Testklassen finden kann:
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
von: http://kostyay.name/Android-studio-robolectric-gradle-getting-work/
Die besten Artikel, die ich dazu gefunden habe, sind:
Dies wird jetzt in Android Studio unterstützt, beginnend mit dem Android Gradle Plugin 1.1.0.
https://developer.Android.com/training/testing/unit-testing/local-unit-tests.html
Beispiel-App mit lokalen Unit-Tests auf GitHub:
https://github.com/googlesamples/Android-testing/tree/master/unittesting/BasicSample
Für Android Studio 1.2+ ist das Einrichten eines Projekts für JUnit ziemlich einfach. Versuchen Sie, diesem Tutorial zu folgen:
Dies ist der einfachste Teil, um ein Projekt für JUnit einzurichten:
https://io2015codelabs.appspot.com/codelabs/Android-studio-testing#1
Folgen Sie dem vorherigen Link bis " Ausführen Ihrer Tests "
Wenn Sie nun den Instrumententest integrieren möchten, folgen Sie hier:
https://io2015codelabs.appspot.com/codelabs/Android-studio-testing#6
Bitte sehen Sie dieses Tutorial auf der offiziellen Website von Android Developers. In diesem Artikel wird auch beschrieben, wie Sie Modelle für Ihre Tests erstellen.
Sie sollten übrigens beachten, dass der Umfang der Abhängigkeiten für den einfachen JUnit-Test "testCompile" sein sollte.