J'utilise Android Studio/IntelliJ
pour créer un projet Android
existant et souhaite ajouter quelques tests unitaires JUnit
simples. Quel est le bon dossier pour ajouter de tels tests?
Le plug-in Gradle
sous Android définit une structure de répertoire avec src/main/Java
pour le code source principal et src/instrumentTest/Java
pour les tests Android
.
Essayer d'ajouter mes tests JUnit dans instrumentTest n'a pas fonctionné pour moi. Je peux l'exécuter comme un test Android
(c'est ce que ce répertoire semble avoir) mais ce n'est pas ce que je recherche - je veux juste exécuter un simple test JUnit
. J'ai essayé de créer une configuration d'exécution JUnit pour cette classe, mais cela n'a pas fonctionné non plus - je suppose parce que j'utilise un répertoire qui est marqué comme Android
Test au lieu de Source.
Si je crée un nouveau dossier source et le marque en tant que tel dans la structure du projet, celui-ci sera effacé lors de la prochaine régénération IntelliJ
de la configuration du projet à partir des fichiers de construction de dégradés.
Quel est le moyen le plus approprié de configurer des tests JUnit dans un projet Android basé sur des graduations sur IntelliJ
? Quelle structure de répertoire utiliser pour cela?
Depuis Android Studio 1.1, la réponse est désormais simple: http://tools.Android.com/tech-docs/unit-testing-support
Normalement, vous ne pouvez pas. Bienvenue dans le monde d'Android, où tous les tests doivent être exécutés sur un appareil (sauf Robolectric).
La raison principale est que vous n'avez pas réellement les sources du framework - même si vous convaincez IDE d'exécuter le test localement, vous obtiendrez immédiatement une exception "Stub! Not Implement" . "Pourquoi? " vous pourriez vous demander? Parce que le Android.jar
que le SDK vous donne est en réalité tout écrasé - toutes les classes et méthodes sont là mais elles jettent toutes une exception. Il est là pour fournir une API mais pas pour vous donner une implémentation réelle.
Il existe un projet merveilleux appelé Robolectric qui implémente une grande partie de la structure afin que vous puissiez exécuter des tests significatifs. Couplé à un bon cadre factice (par exemple, Mockito), il rend votre travail gérable.
Gradle plugin: https://github.com/robolectric/robolectric-gradle-plugin
Notez qu'au moment de la rédaction de ce document, Robolectric 2.4 était la dernière version et ne prend pas en charge la bibliothèque appcompat v7
. Un support sera ajouté à la version robolectric 3.0 (pas encore d’ETA). De plus, ActionBar Sherlock
peut causer des problèmes avec robolectric.
Pour utiliser Robolectric dans Android Studio, vous avez 2 options:
Cette technique utilise un module Java pour tous vos tests avec une dépendance à votre module Android et un programme d'exécution de test personnalisé avec une certaine magie:
Les instructions peuvent être trouvées ici: http://blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-Android-studio/
Vérifiez également le lien à la fin de ce message pour l'exécution des tests à partir du studio Android.
J'ai rencontré quelques problèmes lors de la configuration des tests Junit pour qu'ils s'exécutent graduellement dans Android Studio.
Il s'agit d'un exemple de projet très basique permettant d'exécuter des tests junit à partir d'un projet basé sur plusieurs versions d'Android Studio: https://github.com/hanscappelle/Android-studio-junit-robolectric Ceci a été testé avec Android Studio 0.8.14 , JUnit 4.10, plugin robolectric gradle 0.13+ et robolectric 2.3
Le script de construction est le fichier build.gradle situé à la racine du projet. Là je devais ajouter plugin 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()
}
}
Dans le script de construction de votre module d'application, utilisez le plugin robolectric
, ajoutez robolectric
config et ajoutez les dépendances 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'
}
Placez maintenant les classes de test à l’emplacement par défaut (ou mettez à jour config gradle)
app/src/androidTest/Java
Et nommez vos classes de tests se terminant par Test (ou encore mettez à jour config), en étendant junit.framework.TestCase
et annotez les méthodes de test avec @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;
}
}
Ensuite, exécutez les tests en utilisant gradlew à partir de la ligne de commande (rendez-le exécutable en utilisant chmod +x
si nécessaire)
./gradlew clean test
Exemple de sortie:
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
Tout comme vous pouvez avoir vos fichiers source Java ailleurs, vous pouvez déplacer vos fichiers source de test. Il suffit de mettre à jour gradle sourceSets
config.
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
Java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
androidTest {
setRoot('tests')
}
}
Vous avez oublié d'ajouter la dépendance du test Junit dans le script de construction de l'application.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
}
Vous exécutez ce test avec les configurations d'exécution d'Android Studio au lieu de la ligne de commande (onglet Terminal dans Android Studio). Pour l'exécuter à partir d'Android Studio, vous devez mettre à jour le fichier app.iml
pour que l'entrée jdk soit répertoriée en bas. Voir exemple de deckard-gradle pour plus de détails.
Exemple d'erreur complet:
!!! 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)
Voir cette SO question pour une solution. Ajoutez l'export ci-dessous à votre profil bash:
export Java_HOME=`/usr/libexec/Java_home -v 1.7`
Le journal des erreurs complet:
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.
Si vous souhaitez exécuter vos tests à partir d'Android Studio Junit Test Runner, vous devrez développer un peu plus le fichier build.gradle afin qu'Android Studio puisse trouver vos classes de tests compilées:
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
à partir de: http://kostyay.name/Android-studio-robolectric-gradle-getting-work/
Les meilleurs articles que j'ai trouvés autour de ça sont:
Ceci est maintenant supporté dans Android Studio à partir du plugin Android Gradle 1.1.0, regardez ceci:
https://developer.Android.com/training/testing/unit-testing/local-unit-tests.html
Exemple d'application avec des tests unitaires locaux sur GitHub:
https://github.com/googlesamples/Android-testing/tree/master/unittesting/BasicSample
Pour Android Studio 1.2+, configurer un projet pour JUnit est assez simple essayez de suivre ce tutoriel:
C’est la partie la plus simple de la configuration d’un projet pour JUnit:
https://io2015codelabs.appspot.com/codelabs/Android-studio-testing#1
Suivez le lien précédent jusqu'à " Exécuter vos tests "
Maintenant, si vous souhaitez intégrer un test d'intrumentation, suivez-nous à partir d'ici:
https://io2015codelabs.appspot.com/codelabs/Android-studio-testing#6
S'il vous plaît voir ce tutoriel du site officiel des développeurs Android. Cet article explique également comment créer des maquettes pour vos tests.
A propos, notez que la portée des dépendances pour le test JUnit simple devrait être "testCompile".