web-dev-qa-db-fra.com

Comment exécuter des tests unitaires avec Android Studio

J'utilise Jake's Android plugin de tests unitaires pour Gradle: https://github.com/JakeWharton/gradle-Android-test-plugin

Mon build.gradle ressemble à ceci:

dependencies {
// analytics
compile('com.crittercism:crittercism-Android:3.0.11')

// retrofit
compile('com.squareup.retrofit:retrofit:1.2.2')
compile('com.squareup.okhttp:okhttp:1.2.1')

// dagger
compile('com.squareup.dagger:dagger:1.1.0')
compile('com.squareup.dagger:dagger-compiler:1.1.0')

// compatibility
compile('Android.compatibility:Android-support:v4-r13')
compile('com.actionbarsherlock:actionbarsherlock:4.4.0@aar')

// Picasso
compile('com.squareup.picasso:picasso:2.1.1')

// Otto
compile('com.squareup:otto:1.3.4')

// Tests
testCompile 'junit:junit:4.10'
testCompile 'org.robolectric:robolectric:2.2'
testCompile 'org.powermock:powermock-api-mockito:1.5.1'
testCompile 'org.easytesting:fest-assert-core:2.0M10'
}

Malheureusement, je ne suis pas en mesure d'exécuter tout ou partie du formulaire de test unitaire Android Studio. Je reçois une erreur:

Exception in thread "main" Java.lang.NoClassDefFoundError: junit/textui/ResultPrinter
 at Java.lang.Class.forName0(Native Method)
 at Java.lang.Class.forName(Class.Java:171)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.Java:113)
Caused by: Java.lang.ClassNotFoundException: junit.textui.ResultPrinter
 at Java.net.URLClassLoader$1.run(URLClassLoader.Java:202)
 at Java.security.AccessController.doPrivileged(Native Method)
 at Java.net.URLClassLoader.findClass(URLClassLoader.Java:190)
 at Java.lang.ClassLoader.loadClass(ClassLoader.Java:306)
 at Sun.misc.Launcher$AppClassLoader.loadClass(Launcher.Java:301)
 at Java.lang.ClassLoader.loadClass(ClassLoader.Java:247)
 ... 3 more

Et cela est correct car l'exécution de la ligne de commande n'inclut pas ma dépendance JUnit:

/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/Java -ea -Didea.launcher.port=7533 "-Didea.launcher.bin.path=/Applications/Android Studio.app/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/Android Studio.app/lib/idea_rt.jar:/Applications/Android Studio.app/plugins/junit/lib/junit-rt.jar:/Users/eugen/Development/SDK/Android-sdk-macosx/platforms/Android-18/Android.jar:/Users/eugen/Development/SDK/Android-sdk-macosx/platforms/Android-18/data/res:/Users/eugen/Development/SDK/Android-sdk-macosx/tools/support/annotations.jar:/Users/eugen/Development/Projects/eBuddy/xms/Android/xms3-Android/build/classes/alpha/debug:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.squareup.retrofit/retrofit/1.2.2/jar/cdf7b60568092fbcc7a254371c345e92f733c03c/retrofit-1.2.2.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.google.code.gson/gson/2.2.4/jar/a60a5e993c98c864010053cb901b7eab25306568/gson-2.2.4.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.squareup.okhttp/okhttp/1.2.1/jar/c3562574496bb4d452d6fc45b817577e98d08afe/okhttp-1.2.1.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.squareup/javawriter/2.1.1/jar/67ff45d9ae02e583d0f9b3432a5ebbe05c30c966/javawriter-2.1.1.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.squareup.dagger/dagger/1.1.0/jar/49f2061c938987c8e56679a731d74fd8448d8742/dagger-1.1.0.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.squareup.picasso/picasso/2.1.1/jar/ab19bfb23f641f189b6dca9a4d393f8dc291103a/picasso-2.1.1.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.squareup/otto/1.3.4/jar/4d72fb811c7b3c0e7f412112020d4430f044e510/otto-1.3.4.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.squareup.dagger/dagger-compiler/1.1.0/jar/ddb38c2be31deeb7a001177f7c358665e350d646/dagger-compiler-1.1.0.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/javax.inject/javax.inject/1/jar/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar:/Users/eugen/Development/Projects/eBuddy/xms/Android/xms3-Android/build/exploded-bundles/ComActionbarsherlockActionbarsherlock440.aar/res:/Users/eugen/Development/Projects/eBuddy/xms/Android/xms3-Android/build/exploded-bundles/ComActionbarsherlockActionbarsherlock440.aar/classes.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.squareup.okhttp/okhttp-protocols/1.2.1/jar/ec2beaefef3bd4f680c17fad8e72e66f2a006f1/okhttp-protocols-1.2.1.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/com.crittercism/crittercism-Android/3.0.11/jar/e30c21ae491d780622ecaee2752969be98140c3/crittercism-Android-3.0.11.jar:/Users/eugen/.gradle/caches/artifacts-26/filestore/Android.compatibility/Android-support/v4-r13/jar/bd6479f5dd592790607e0504e66e0f31c2b4d308/Android-support-v4-r13.jar" com.intellij.rt.execution.application.AppMain com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 @/private/var/folders/wq/knhztnf105v2_p1t580tj8h80000gp/T/idea_junit701450667388095664.tmp @w@/private/var/folders/wq/knhztnf105v2_p1t580tj8h80000gp/T/idea_working_dirs_junit4927192380605663413.tmp -socket63849

Je me demande si quelqu'un a pu exécuter des tests unitaires dans Android Studio? Et s'il est possible comment le faire?

28
Eugen Martynov

Mise à jour pour AS 1.1+, Android plugin gradle 1.1 +

Enfin c'est possible sans beaucoup de trucs. Voici un exemple de projet qui montre comment configurer Robolectric test dans Android Studio v1.1+ et Android gradle plugin v1.1+: https://github.com/nenick/AndroidStudioAndRobolectric

Vous pouvez également y trouver d'éventuels problèmes et solutions. Oui, Robolectric est complexe et n'est pas officiellement pris en charge par Google, il a donc encore quelques problèmes. Mais la plupart du temps, cela fonctionne et apporte une valeur énorme à votre projet.

Je vous encourage également à commencer à utiliser Robolectric v3+. Il est presque sorti et assez stable.

Ancienne réponse pour AS 0.x et 1.0x et Android version du plugin gradle en dessous de 1.1

J'ai réussi à le faire avec l'aide d'amis.

Donc, fondamentalement, vous devez apporter les modifications suivantes pour exécuter les tests unitaires Robolectric dans Android Studio:

  1. Copiez votre chemin de classe pour le test (vous pouvez le trouver comme première ligne dans le journal "Exécuter")
  2. Configuration d'exécution ouverte pour vos tests unitaires
  3. Changer le répertoire de travail dans le dossier où AndroidManifest.xml est présent
  4. Ajouter VM Option -classpath "<path_to_project_folder>/build/test-classes:<path_to_gradle_cache>/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar:<your old classpath>"

Quant à moi, le début d'un nouveau chemin de classe ressemble à ceci:

/Users/emartynov/Development/Projects/work/Android.project/build/test-classes:/Users/emartynov/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar

Problèmes:

  1. Vous pouvez exécuter le test uniquement pour la variante de débogage
  2. Chaque nouvelle configuration de test nécessite de telles modifications manuelles. Mais il s'agit simplement de copier/coller de deux champs d'édition

J'ai Android version Studio 0.6. Voici à nouveau une partie de mon build.gradle fichier:

buildscript {
  repositories {
    mavenCentral()
    maven { url 'https://github.com/rockerhieu/mvn-repo/raw/master/' }
  }

  dependencies {
    classpath 'com.Android.tools.build:gradle:0.11.+'
    classpath 'com.neenbedankt.gradle.plugins:Android-apt:1.3'
  //  classpath 'org.robolectric.gradle:gradle-Android-test-plugin:0.10.1'
    classpath 'org.robolectric.gradle:gradle-Android-test-plugin:0.10.1-SNAPSHOT'
    classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.10.+'
  }
}

apply plugin: 'Android-sdk-manager'
apply plugin: 'Android'
apply plugin: 'Android-apt'
apply plugin: 'Android-test'

repositories {
  mavenCentral()
}

Android {
  compileSdkVersion 19
  buildToolsVersion "19.1.0"

  packagingOptions {
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/notice.txt'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/ASL2.0'
    exclude 'LICENSE.txt'
  }

  defaultConfig {
    minSdkVersion 14
    targetSdkVersion 19
    versionCode 1
    versionName "0.9.0"
  }

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
  }

  sourceSets {
    androidTest.setRoot( 'src/test' )
  }
}

dependencies {
  // butter knife
  compile 'com.jakewharton:butterknife:5.0.0'
  // dagger
  compile 'com.squareup.dagger:dagger:1.2.1'

  // apt
  apt 'com.squareup.dagger:dagger-compiler:1.+'

  // AS tests
  androidTestCompile 'junit:junit:4.+'
  androidTestCompile( 'org.robolectric:robolectric:2.3' ) {
    exclude group: 'commons-logging'
    exclude group: 'org.Apache.httpcomponents'
  }
  androidTestCompile 'com.squareup:fest-Android:1.+'
  androidTestCompile 'org.mockito:mockito-all:1.9.+'
  androidTestCompile 'org.easytesting:fest-assert-core:2.0M10'
  androidTestCompile( 'org.skyscreamer:jsonassert:1.2.+' ) {
    exclude group: 'org.json'
  }

  // tests
  testCompile 'junit:junit:4.+'
  testCompile( 'org.robolectric:robolectric:2.3' ) {
    exclude group: 'commons-logging'
    exclude group: 'org.Apache.httpcomponents'
  }
  testCompile 'com.squareup:fest-Android:1.+'
  testCompile 'org.mockito:mockito-all:1.9.+'
  testCompile 'org.easytesting:fest-assert-core:2.0M10'
  testCompile 'com.squareup.dagger:dagger-compiler:1.+'
  testCompile( 'org.skyscreamer:jsonassert:1.2.+' ) {
    exclude group: 'org.json'
  }
}
10
Eugen Martynov

il suffit d'ajouter le dossier nommé instrumentTest sous/src, il devrait avoir/Java à l'intérieur comme ceci

enter image description here

puis étendez la classe ActivityTestCase (ou tout autre Android unit-test-class), tel que

package com.example.app.test;

import Android.test.ActivityTestCase;

import junit.framework.Assert;


public class MainActivityTest extends ActivityTestCase {


public void testHappy(){
    Assert.assertTrue(true);
}

} 

faites un clic droit sur le répertoire vert Java et sélectionnez exécuter tous les tests et vous devriez obtenir ceci:

enter image description here

bonne chance

28
zebra

J'ai rencontré ce problème et j'ai trouvé une solution - incluez le fichier classes.jar du paquet éclaté (.aar) dans le dossier de construction. Je ne pense pas que cela aidera à trouver des ressources dans les dépendances .aar.

testCompile fileTree(dir: "$project.buildDir/exploded-bundles", include: "**/classes.jar")

Edit: Depuis Android Outils de construction Gradle .9. la dépendance a changé en:

androidTestCompile fileTree(dir: "$project.buildDir/exploded-aar", include: "**/classes.jar")

Edit 2: Depuis Android Outils de construction Gradle .10. la dépendance a changé en:

androidTestCompile fileTree(dir: "$project.buildDir/../../build/exploded-aar", include: "**/classes.jar")

Remarque: le chemin relatif peut être différent selon la structure de votre projet.

2
myanimal

Pour la postérité Android Studio 2.0 + prend en charge l'exécution de tests unitaires sans plugins.

JUnit configuration in Android Studio 2.0+

Cet écran est accessible via le menu Exécuter> Modifier les configurations ...

0
scottyab

J'ai eu un problème similaire avec AS 1.2.2.

J'ai suivi les étapes ici . Fondamentalement:

  • Ouverture de la fenêtre de l'outil "Build Variants" (voir l'image sur le lien) et modification du menu déroulant "Test Artifact" en "Unit tests".
  • Créez un répertoire pour votre code source de test, c'est-à-dire src/test/Java, et déplacez votre test vers le package correspondant.
  • Assurez-vous que les sections suivantes de votre build.gradle le fichier contient ces éléments:

    dependencies { 
        testCompile 'junit:junit:4.12'
    }
    
    Android {
        sourceSets {
            test {
                resources {
                    srcDir "test"
                }
            }
        }
    }
    

Voila! Cliquez avec le bouton droit sur votre scénario de test et sélectionnez la saveur JUnit.

BTW, il semble basculer la visibilité des tests JUnit/Android lorsque vous changez l'outil "Build Variants", donc je suppose que vous pouvez soit tester en JUnit ou Android mais pas les deux en même temps) temps.

0
ocarlsen