使用基于Gradle的配置时在Android Studio(IntelliJ)上运行简单的JUnit测试


78

Android Studio/IntelliJ用来构建现有Android项目,并想添加一些简单的JUnit单元测试。添加此类测试的正确文件夹是什么?

所述机器人Gradle插件定义的目录结构与src/main/java主源代码和src/instrumentTest/java用于Android测试。

尝试在instrumentTest中添加我的JUnit测试对我不起作用。我可以将其作为Android测试运行(这就是该目录的用途),但这不是我想要的-我只想运行一个简单的JUnit测试。我尝试为此类创建一个JUnit运行配置,但是也没有用-我想是因为我使用的是标记为AndroidTest而不是Source的目录。

如果我创建一个新的源文件夹并将其标记为“项目结构”,则下次IntelliJ从gradle构建文件中刷新项目配置时,该文件夹将被擦除。

在基于gradle的android项目中配置JUnit测试的更合适的方法是IntelliJ什么?为此使用哪种目录结构?


不幸的是,我不能帮你的测试,我还在这个自己挣扎,但你可以用它来停止的IntelliJ擦源文件夹:java.srcDirs = ['src/main/java','src/instrumentTest/java']sourceSets一节的build.gradle
罗布福尔摩斯

它不好玩成立,也没有维护简单,但我不知怎么把它使用运行在默认的/src/androidTest/java文件夹robolectric JUnit测试,请参阅:stackoverflow.com/a/25473702/1406325
弗洛

Android Studio现在支持使用JUnit 4进行本地单元测试:stackoverflow.com/a/30273301/885464
Lorenzo Polidori,2015年

@Julian Cerruti更新:有关如何运行测试用例goo.gl/ac06C0的Android Studio演示以及运行网络调用测试goo.gl/bQFlmU的示例
nitesh,2015年

测试和测试类的目录结构必须适合。这是轻松实现的方法:stackoverflow.com/a/36057080/715269
Gangnus

Answers:


23

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


4
这是否意味着Robolectric不再有用?这基本上会做同样的事情吗?
David Argyle Thacker,2015年

1
注意:自Android Studio 2.0 Beta5起,链接中描述“测试工件”选择器的内容已丢失,并且默认情况下同时启用了两种模式(junit和仪器)。在这里看到更多的信息stackoverflow.com/questions/35708263/...
帕特里克·法弗

36

通常,您不能。欢迎来到Android的世界,所有测试都必须在设备上运行(Robolectric除外)。

主要原因是您实际上没有框架的来源-即使您说服IDE在本地运行测试,您也会立即收到“ Stub!未实现”异常。“为什么?” 你可能想知道吗?因为该android.jarSDK给您的实际上已经被淘汰了-所有类和方法都在那里,但它们都抛出异常。它在那里提供API,但不提供任何实际实现。

有一个很棒的项目叫Robolectric,它实现了很多框架,因此您可以运行有意义的测试。加上良好的模拟框架(例如Mockito),它使您的工作易于管理。

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


1
谢谢迪伦 我正在进行不使用任何Android基础结构的简单测试,因此,按照您的建议创建一个新项目,或者调整Gradle Android配置以适应常规测试将是您的选择。不幸的是,我仍然无法使它正常工作-它因某种原因而一直失败-但如果我使它正常工作,它将发布结果
朱利安·塞鲁蒂

1
在这种情况下,您想创建一个新的普通Java Gradle项目(即apply plugin: 'java'),将其添加到“ settings.gradle”,使其成为Android项目的依赖项(compile project(':plainJavaProjectName')),然后运行test任务。(未经测试,但绝对可以工作!)
Delyan

3
在普通的Java gradle项目中,测试可以在命令行上正常运行,但在Android Studio内却无法正常工作,因为我收到“找不到类MyTestClass”错误。这很奇怪,因为AS和命令行应该以相同的方式使用gradle。
lukas 2013年

1
如果要使用JUnit测试,请避免使用gradle,maven是更好的选择。
Jeroen 2014年

3
你能证明这个说法合理吗?为什么Maven更好?
RichieHH 2014年

32

介绍

请注意,在撰写本文时,robolectric 2.4是最新版本,并且不支持appcompat v7库。支持将在robolectric 3.0版本中添加(尚无ETA)。也ActionBar Sherlock可能引起robolectric问题。

要在Android Studio中使用Robolectric,您有两种选择:

(选项1)-使用Java模块在Android Studio中运行JUnit测试

该技术将Java模块用于所有测试,并依赖于android模块,并使用一些魔术来定制测试运行器:

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

另外,请检查该博文末尾的链接,以从android studio运行测试。

(选项2)-使用robolectric-gradle-plugin在Android Studio中运行JUnit测试

我在设置junit测试以从Android Studio的gradle中运行时遇到了一些问题。

这是一个非常基本的示例项目,用于在Android Studio中从基于gradle的项目中运行junit测试: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.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()
    }
}

项目构建脚本(App / build.gradle)

在您的应用模块的构建脚本中,使用robolectric插件,添加robolectric配置并添加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'
}

创建JUnit测试类

现在将测试类放在默认位置(或更新gradle配置)

app/src/androidTest/java

并命名测试类以Test结尾(或再次更新config),junit.framework.TestCase并使用扩展和注释测试方法@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;
    }
}

执行测试

接下来,在命令行中使用gradlew执行测试(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源文件放在其他位置一样,您可以移动测试源文件。只需更新gradlesourceSets配置。

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

        androidTest {
            setRoot('tests')
        }
    }

软件包org.junit不存在

您忘记在应用程序构建脚本中添加junit测试依赖项

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

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

java.lang.RuntimeException:存根!

您正在使用Android Studio的运行配置而不是命令行(Android Studio中的“终端”标签)运行此测试。要从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设置为无效目录

请参阅此SO问题以获取解决方案。将以下导出添加到您的bash配置文件中:

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.

找不到测试班

如果您想从Android Studio Junit TestRunner运行测试,则必须再扩展build.gradle文件,以便android studio可以找到编译后的测试类:

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/

更多资源

我发现的最佳文章是:




0

请参阅Android开发者官方网站上的本教程。本文还介绍了如何为您的测试创建模型。

顺便说一句,您应注意,简单JUnit测试的依赖项范围应为“ testCompile”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.