如何使用Android Studio运行单元测试

时间:2013-11-10 15:34:27

标签: android junit gradle android-studio robolectric

我正在使用Jake的Android单元测试插件进行gradle:https://github.com/JakeWharton/gradle-android-test-plugin

我的build.gradle看起来像这样:

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

不幸的是,我无法运行所有或特定的单元测试表单Android Studio。我收到了错误:

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

这是正确的,因为运行命令行不包含我的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

我想知道是否有人能够在Android Studio中运行单元测试?如果有可能怎么做呢?

5 个答案:

答案 0 :(得分:28)

只需在/ src下添加名为instrumentTest的文件夹即可 它应该像这样的/ java内部

enter image description here

然后扩展ActivityTestCase类(或任何其他android单元测试类),例如

package com.example.app.test;

import android.test.ActivityTestCase;

import junit.framework.Assert;


public class MainActivityTest extends ActivityTestCase {


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

} 

右键单击绿色java目录并选择运行所有测试 你应该得到这个:

enter image description here

祝你好运

答案 1 :(得分:10)

更新AS 1.1 +,android gradle插件1.1 +

最后有可能没有很多技巧。以下是展示如何在RobolectricAndroid Studio v1.1+中设置android gradle plugin v1.1+测试的项目示例: https://github.com/nenick/AndroidStudioAndRobolectric

您也可以找到可能存在的问题和解决方法。是的,Robolectric很复杂,Google没有正式支持,所以它仍然存在一些问题。但大部分时间它都有效,并为您的项目带来巨大价值。

我还鼓励您开始使用Robolectric v3+。它几乎被释放并且足够稳定。

AS 0.x和1.0x的旧答案以及1.1以下的android gradle插件版本

我设法在朋友的帮助下成功。

所以基本上你需要进行下一次更改才能在Android Studio中运行Robolectric单元测试:

  1. 复制您的类路径以进行测试(您可以在&#34中找到第一行;运行"日志)
  2. 单元测试的开放运行配置
  3. 将工作目录更改为存在AndroidManifest.xml的文件夹
  4. 添加VM选项-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>"
  5. 对于我来说,新类路径的开头如下所示:

    /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
    

    问题:

    1. 您只能为调试变体运行测试
    2. 每个新的测试运行配置都需要进行此类手动更改。但这只是两个编辑字段的复制/粘贴
    3. 我有Android Studio 0.6版本。这又是我build.gradle文件的一部分:

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

答案 2 :(得分:2)

我遇到了这个问题并找到了一个解决方案 - 在build文件夹中包含来自爆炸包(.aar)的classes.jar。我不认为有助于在.aar依赖项中查找资源。

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

修改:由于Android Gradle构建工具 0.9.0 ,因此依赖关系已更改为:

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

编辑2 :由于Android Gradle构建工具 0.10.0 ,因此相关性已更改为:

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

注意:相对路径可能因项目结构而异。

答案 3 :(得分:0)

我在AS 1.2.2中遇到了类似的问题。

我按照here步骤进行了操作。基本上是:

  • 打开&#34; Build Variants&#34;工具窗口(见链接上的图像)并更改了&#34;测试工件&#34;下拉到&#34;单元测试&#34;。
  • 为您的测试源代码创建一个目录,即src/test/java,并将您的测试移至相应的包中。
  • 确保build.gradle文件的以下部分包含以下内容:

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

瞧!右键单击您的测试用例并选择JUnit flavor。

顺便说一下,当您更改&#34; Build Variants&#34;时,它似乎会切换JUnit / Android测试的可见性。工具,所以我猜你可以测试JUnit或Android,但不能同时测试。

答案 4 :(得分:0)

后人 Android Studio 2.0 + 支持在没有插件的情况下运行单元测试。

JUnit configuration in Android Studio 2.0+

可以通过菜单Run&gt;访问此屏幕。编辑配置...