带有Gradle的Robolectric:未找到资源

pas*_*ssy 31 android gradle robolectric

我正在尝试与新的Gradle Android构建系统一起运行我的Robolectric测试,但我一直在访问我的主项目的资源.

我将构建拆分为两个单独的项目,以避免javaandroidgradle插件之间发生冲突,因此目录结构大致如下所示:

.
??? build.gradle
??? settings.gradle
??? mainproject
?   ??? build
?   ?   ??? classes
?   ?   ?   ??? debug
?   ??? build.gradle
?   ??? src
?       ??? main
?           ??? AndroidManifest.xml
?           ??? ...
??? test
    ??? build.gradle
    ??? src
        ??? test
            ??? java
                ??? ...
                    ??? test
                        ??? MainActivityTest.java
                        ??? Runner.java
                        ??? ServerTestCase.java
                        ??? StatusFetcherTest.java
Run Code Online (Sandbox Code Playgroud)

build.gradletest/目前看起来是这样的:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.stanfy.android:gradle-plugin-java-robolectric:2.0'
    }
}

apply plugin: 'java-robolectric'

repositories {...}

javarob {
    packageName = 'com.example.mainproject'
}

test {
    dependsOn ':mainproject:build'
    scanForTestClasses = false
    include "**/*Test.class"
    // Oh, the humanity!
    def srcDir = project(':mainproject').android.sourceSets.main.java.srcDirs.toArray()[0].getAbsolutePath()
    workingDir srcDir.substring(0, srcDir.lastIndexOf('/'))
}

project(':mainproject').android.sourceSets.main.java.srcDirs.each {dir ->
    def buildDir = dir.getAbsolutePath().split('/')
    buildDir =  (buildDir[0..(buildDir.length - 4)] + ['build', 'classes', 'debug']).join('/')

    sourceSets.test.compileClasspath += files(buildDir)
    sourceSets.test.runtimeClasspath += files(buildDir)
}

dependencies {    
    testCompile group: 'com.google.android', name: 'android', version: '4.1.1.4'
    testCompile group: 'org.robolectric', name: 'robolectric', version: '2.0-alpha-3'
    ...
}
Run Code Online (Sandbox Code Playgroud)

邪恶的classpath hackery允许我访问我的主项目的所有类,除了在构建目录中R作为.class文件存在,但在compileTestJava任务期间引发此错误:

/.../MainActivityTest.java:16: error: cannot find symbol
                final String appName = activity.getResources().getString(R.string.app_name);
                                                                          ^
  symbol:   variable string
  location: class R
1 error
:test:compileTestJava FAILED
Run Code Online (Sandbox Code Playgroud)

必须有一种更好的方法来使用新的构建系统执行Robolectric测试,对吗?

(应用程序的完整来源)

小智 27

我遇到了同样的问题,这就是我提出的问题.我没有为测试创建单独的项目,而是为Robolectric测试创建了一个源集,并添加了一个"check"依赖的新任务.使用您问题中的一些代码,这里是(工作)构建文件的相关位:

apply plugin: 'android'

sourceSets {
    testLocal {
        java.srcDir file('src/test/java')
        resources.srcDir file('src/test/resources')
    }
}

dependencies {
    compile 'org.roboguice:roboguice:2.0'
    compile 'com.google.android:support-v4:r6'

    testLocalCompile 'junit:junit:4.8.2'
    testLocalCompile 'org.robolectric:robolectric:2.1'
    testLocalCompile 'com.google.android:android:4.0.1.2'
    testLocalCompile 'com.google.android:support-v4:r6'
    testLocalCompile 'org.roboguice:roboguice:2.0'
}

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
Run Code Online (Sandbox Code Playgroud)

我已经包含了我的依赖项块指出,为了让我能够实现这一点,我必须compile在自定义testLocal源集中重复所有依赖项.

运行gradle testLocal构建并运行其中的测试src/test/java,同时运行gradle check除了默认的android instrumentTest源集中的测试之外还运行这些测试.

希望这可以帮助!

  • 再次感谢,@ user2457888.:)我将`localTest`任务中的`workingDir`设置为`src/main`,现在它找到`AndroidManifest.xml`和所有资源. (3认同)

Saa*_*ooq 8

更新: 杰克沃顿刚宣布了gradle-android-test-plugin.您可以在https://github.com/square/gradle-android-test-plugin找到它

它看起来非常简化,特别是如果你打算使用它robolectric.


下面的旧答案

robolectric-plugin看起来很有希望.

build.gradle他们提供的示例文件是:

buildscript {
    repositories {
        mavenCentral()
        maven {
            url "https://oss.sonatype.org/content/repositories/snapshots"
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.4.2'
        classpath 'com.novoda.gradle:robolectric-plugin:0.0.1-SNAPSHOT'
    }
}

apply plugin: 'android'
apply plugin: 'robolectric'

repositories {
    mavenCentral()
    mavenLocal()
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots"
    }
}

dependencies {
    //compile files('libs/android-support-v4.jar')

    // had to deploy to sonatype to get AAR to work
    compile 'com.novoda:actionbarsherlock:4.3.2-SNAPSHOT'

    robolectricCompile 'org.robolectric:robolectric:2.0'
    robolectricCompile group: 'junit', name: 'junit', version: '4.+'
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 17
    }
}
Run Code Online (Sandbox Code Playgroud)

它似乎不适用于Android Gradle插件版本0.5,但也许很快就会出现.

  • 似乎Jake Wharton的插件现在已被弃用? (2认同)