在使用基于Gradle的configuration时,在Android Studio(IntelliJ)上运行简单的JUnittesting

我正在使用Android Studio/IntelliJ构build现有的Android项目,并希望添加一些简单的JUnitunit testing。 什么是正确的文件夹添加这样的testing?

Android Gradle插件定义了一个目录结构,主要源代码为src/main/java src/instrumentTest/javaAndroidtesting为src/instrumentTest/java

试图在instrumentTest中添加我的JUnittesting对我不起作用。 我可以运行它作为一个Androidtesting(这就是目录似乎),但这不是我所期待的 – 我只是想运行一个简单的JUnittesting。 我试图创build一个JUnit运行configuration这个类,但也没有工作 – 我假设,因为我使用的标记为Androidtesting代替源的目录。

如果我在Project Structure中创build了一个新的源文件夹并将其标记为marki,那么下次IntelliJ将从Gradle构build文件中刷新项目configuration时将被擦除。

IntelliJ上基于gradle的android项目中configurationJUnittesting的更合适的方法是什么? 使用哪种目录结构?

从Android Studio 1.1开始,现在的答案很简单: http : //tools.android.com/tech-docs/unit-testing-support

通常情况下,你不能。 欢迎来到Android的世界,所有testing必须在设备上运行(Robolectric除外)。

主要原因是你实际上没有框架的源代码 – 即使你说服IDE在本地运行testing,你将立即得到一个“Stub!not implemented”exception。 “为什么?” 你可能想知道? 因为SDK提供给你的android.jar实际上全部被删除了 – 所有的类和方法都在那里,但是它们都抛出exception。 在那里提供一个API,但不是在那里给你任何实际的实现。

有一个叫做Robolectric的精彩项目,它实现了很多框架,所以你可以运行有意义的testing。 再加上一个好的模拟框架(例如,Mockito),它使你的工作易于pipe理。

Gradle插件: https : //github.com/robolectric/robolectric-gradle-plugin

介绍

请注意,在撰写本文时,robolectric 2.4是最新版本,不支持appcompat v7库。 支持将被添加在robolectric 3.0版本( 没有ETA呢 )。 另外ActionBar Sherlock可能会导致robolectric问题。

要在Android Studio中使用Robolectric,您有两个选项:

(选项1) – 使用Java模块运行Android Studio的JUnittesting

这个技术使用了一个java模块来进行所有的testing,并且依赖于你的android模块和一个自定义的testing运行器。

说明可以在这里find: http : //blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-android-studio/

另外检查该post末尾的链接,以从android studio运行testing。

(选项2) – 使用robolectric-gradle-plugin在Android Studio中运行JUnittesting

我在Android Studio中遇到了一些设置junittesting从gradle运行的问题。

这是一个非常基本的示例项目,用于在Android Studio中运行基于gradle的项目的junittesting: https : //github.com/hanscappelle/android-studio-junit-robolectric这已经在Android Studio 0.8.14,JUnit 4.10, robolectric gradle插件0.13+和robolectric 2.3

Buildscript(project / build.gradle)

构build脚本是项目根目录中的build.gradle文件。 在那里,我不得不将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() } } 

Project buildscript(App / build.gradle)

在应用程序模块的构build脚本中使用robolectric插件,添加robolectricconfiguration并添加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' } 

创buildJUnittesting类

现在把testing类放在默认位置(或更新gradleconfiguration)

 app/src/androidTest/java 

并命名您的testing类以Test结束(或再次更新configuration),扩展junit.framework.TestCase和用@Test注释testing方法。

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

执行testing

接下来使用gradlew从命令行执行testing(如果需要,使用chmod +x来使其可执行)

 ./gradlew clean test 

示例输出:

 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 

故障排除

替代源目录

就像你可以在其他地方有你的Java源文件一样,你可以移动你的testing源文件。 只需更新gradle sourceSetsconfiguration。

  sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } androidTest { setRoot('tests') } } 

包org.junit不存在

您忘了在应用程序构build脚本中添加junittesting依赖项

 dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile 'org.robolectric:robolectric:2.3' androidTestCompile 'junit:junit:4.10' } 

java.lang.RuntimeException:存根!

您正在使用Android Studio的运行configuration而不是命令行(Android Studio中的“terminal”选项卡)运行此testing。 要从Android Studio中运行它,您必须更新app.iml文件以在底部列出jdk条目。 有关详细信息,请参阅deckard-gradle示例 。

完整的错误示例:

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

错误:JAVA_HOME被设置为一个无效的目录

看到这个问题的解决scheme。 将下面的导出添加到你的bashconfiguration文件中:

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

完整的错误日志:

 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. 

testing类未find

如果您想从Android Studio Junit Test runner运行testing,则需要再扩展build.gradle文件,以便android studio可以find您编译的testing类:

 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 

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

一些更多的资源

我发现最好的文章是:

Android Studio现在支持从Android Gradle插件1.1.0开始,请检查:

https://developer.android.com/training/testing/unit-testing/local-unit-tests.html

在GitHub上使用本地unit testing的示例应用程序:

https://github.com/googlesamples/android-testing/tree/master/unittesting/BasicSample

对于Android Studio 1.2+JUnit设置项目非常简单 ,请遵循本教程:

这是为JUnit设置项目最简单的部分:

https://io2015codelabs.appspot.com/codelabs/android-studio-testing#1

沿着过去的链接,直到“ 运行你的testing ”

现在,如果您想与入门testing进行整合,请按照以下步骤进行:

https://io2015codelabs.appspot.com/codelabs/android-studio-testing#6

请参阅Android Developers官方网站上的这个教程 。 本文还展示了如何为您的testing创build模型。

顺便说一句,你应该注意到简单的JUnittesting的依赖范围应该是“testCompile”。