78 votes

En cours d’exécution des tests JUnit simples sur Android Studio (IntelliJ) lorsque vous utilisez une configuration basée sur Gradle

Je suis l'aide d' Android Studio/IntelliJ de construire sur un Android projet et souhaitez ajouter des simples JUnit des tests unitaires. Quel est le dossier à droite pour ajouter de tels tests?

L'androïde Gradle plug-in définit une structure de répertoire avec des src/main/java pour le code source principal et src/instrumentTest/java pour Android tests.

Essayez d'ajouter mon JUnit tests dans instrumentTest ne fonctionne pas pour moi. Je peux l'exécuter en tant qu' Android test (c'est ce que le répertoire semble) mais ce n'est pas ce que je cherche: je veux juste faire un simple JUnitde test. J'ai essayé de créer un JUnit configuration d'essai pour cette Classe, mais qui n'a pas de travail, je suis en supposant que parce que je suis en utilisant un répertoire qui est marqué en tant que Android Test au lieu de la Source.

Si je crée un nouveau dossier source et marki en tant que tel dans le Projet de la Structure, cela permet d'obtenir des essuyé la prochaine fois, IntelliJ actualise la configuration du projet à partir des fichiers de build gradle.

Quel est le moyen le plus approprié de la configuration de JUnit tests dans un gradle-fondé du projet android sur IntelliJ? Qui structure de répertoire à utiliser pour cela?

36voto

Delyan Points 5243

Normalement, vous ne pouvez pas. Bienvenue dans le monde d'Android, où tous les tests doivent s'exécuter sur un périphérique.

La raison principale est que vous n'avez pas réellement le cadre de ses sources, même si vous les convaincre de l'IDE pour exécuter le test en local, vous recevrez immédiatement un "Stub! Pas mis en œuvre" l'exception". "Pourquoi?" vous pourriez vous demander? Parce que l' android.jar que le kit de développement vous donne est en fait tout écrasé - toutes les classes et les méthodes sont là, mais ils ont tous simplement lever une exception. Il est là pour fournir une API, mais pas là pour vous donner toute mise en œuvre effective.

Il y a un merveilleux projet appelé Robolectric qui met en œuvre beaucoup de le cadre, de sorte que vous pouvez exécuter des tests significatifs. Couplé avec une bonne maquette cadre (par exemple, Mockito), il rend votre travail gérable.

Sauf que Gradle ne le supporte pas de n'importe quelle forme. Officiellement. (c'est assez facile à mettre en place avec le maven-android-plugin, il vaut la peine de prendre un coup d'oeil à l')

Unofficiallly, vous pourriez tenter d'utiliser robolectric-plugin à partir de la gens merveilleux à Novoda.

EDIT: Le Novoda plugin n'est plus activement développé, veuillez utiliser Jake Wharton est merveilleux gradle-android-test-plugin!

Oh, et puis c'est une grande douleur pour convaincre le Studio à l'instar de ceux sources de test!

Dans l'ensemble, Robolectric test est une douleur à mettre en place avec Gradle et je vous suggère de vous éviter toute Gradle créer une chaîne si vous en avez absolument besoin.

P. S. Si vos tests ne touche pas vraiment Android, il suffit de faire un simple java Gradle projet, ajoutez-la à la dépendance à votre projet Android et de mettre votre non-Android code et des tests.

32voto

hcpl Points 5759

L'exécution de Tests JUnit avec Android Studio à l'aide de robolectric

J'ai rencontré quelques problèmes de réglage jusqu'junit tests à exécuter à partir de gradle dans Android Studio.

C'est un exemple très simple du projet pour l'exécution des tests junit à partir d'un gradle projet basé sur Android Studio: https://github.com/hanscappelle/android-studio-junit-robolectric Cela a été testé avec Android Studio 0.8.14, JUnit 4.10, robolectric plugin gradle 0.13+ et robolectric 2.3

Buildscript (project/build.gradle)

Le script de construction est la construction.gradle fichier dans la racine de votre projet. Là, j'ai dû ajouter de la robolectric plugin gradle pour 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()
    }
}

Projet buildscript (App/build.gradle)

Dans le script de création de votre application module d'utiliser l' robolectric plugin, ajouter robolectric config et ajouter androidTestCompile dépendances.

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'
}

Créer Des Classes De Test JUnit

Maintenant, mettez les classes de test dans l'emplacement par défaut (ou mise à jour de gradle config)

app/src/androidTest/java

Et le nom de vos classes de tests de fin de Test (ou encore de mise à jour de config), s'étendant junit.framework.TestCase et annoter des méthodes d'essai 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;
    }
}

L'Exécution Des Tests

Prochaine exécuter les tests en utilisant gradlew en ligne de commande (le rendre exécutable à l'aide de 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

Dépannage

autre source répertoires

Tout comme vous pouvez avoir vos fichiers source java ailleurs que vous pouvez déplacer votre test fichiers sources. Juste mettre à jour gradle sourceSets config.

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        androidTest {
            setRoot('tests')
        }
    }

package org.junit n'existe pas

Vous avez oublié d'ajouter la junit test de dépendance à l'application du script de création

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    androidTestCompile 'org.robolectric:robolectric:2.3'
    androidTestCompile 'junit:junit:4.10'
}

java.lang.RuntimeException: Stub!

Vous êtes l'exécution de ce test avec la configuration à partir d'Android Studio, au lieu de la ligne de commande (Terminal onglet dans Android Studio). Pour l'exécuter à partir d'Android Studio, vous aurez à mettre à jour l' app.iml le fichier pour avoir le jdk entrée listés en bas. Voir deckard-gradle exemple pour plus de détails.

Complet exemple d'erreur:

!!! 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)

ERREUR: JAVA_HOME est fixé à un répertoire non valide

Voir ce DONC, la question pour trouver une solution. Ajouter le dessous de l'exportation de vous bash profil:

export JAVA_HOME=`/usr/libexec/java_home -v 1.7`  

Complète du journal des erreurs:

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.

La Classe de Test non trouvé

Si vous souhaitez exécuter vos tests à partir de Android Studio de Test Junit coureur au lieu de cela, vous aurez à développer le construire.gradle fichier un peu plus, de sorte que android studio pouvez trouver votre compilé classes de test:

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
    instrumentTestCompile 'junit:junit:4.11'
    instrumentTestCompile 'com.google.android:android:4.1.1.4'
    instrumentTestCompile '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

de: http://kostyay.name/android-studio-robolectric-gradle-getting-work/

Certains plus de ressources

Les meilleurs articles que j'ai trouvé autour de cette question sont:

2voto

ligi Points 8318

ce plugin gradle est également une option : https://github.com/square/gradle-android-test-plugin

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X