简体   繁体   English

带有Gradle的Robolectric:未找到资源

[英]Robolectric with Gradle: Resources not found

I'm trying to run my Robolectric tests together with the new Gradle Android build system, but I'm stuck at accessing the resources of my main project. 我正在尝试与新的Gradle Android构建系统一起运行我的Robolectric测试,但我一直在访问我的主项目的资源。

I split the build into two separate projects to avoid conflicts between the java and the android gradle plugins, so the directory structure looks roughly like this: 我将构建拆分为两个独立的项目,以避免javaandroid gradle插件之间的冲突,因此目录结构看起来大致如下:

.
├── 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

My build.gradle in test/ currently looks like this: 我的build.gradle in test/目前看起来像这样:

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

The evil classpath hackery allows me to access all classes of my main project, except for R , which exists as .class file in the build directory, but raises this error during the compileTestJava task: 邪恶的classpath hackery允许我访问我的主项目的所有类,除了R ,它在build目录中以.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

There must be a better way to execute Robolectric tests with the new build system, right? 必须有一种更好的方法来使用新的构建系统执行Robolectric测试,对吗?

( Full source of the app ) 应用程序的完整来源

I was running across this same issue and this is what I came up with. 我遇到了同样的问题,这就是我提出的问题。 Instead of creating a separate project for the tests, I created a source set for the Robolectric tests and added a new task that "check" would depend on. 我没有为测试创建单独的项目,而是为Robolectric测试创建了一个源集,并添加了一个“check”依赖的新任务。 Using some of the code from your question, here are the relevant bits of the (working) build file: 使用您问题中的一些代码,这里是(工作)构建文件的相关位:

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

I've included my dependencies block to point out that in order for me to get this up and going, I had to repeat all of my compile dependencies in my custom testLocal source set. 我已经包含了我的依赖项块,指出为了让我能够实现这一目标,我必须在自定义testLocal源集中重复所有compile依赖项。

Running gradle testLocal builds and runs just the tests inside of src/test/java , while running gradle check runs these tests in addition to those in the default android instrumentTest source set. 运行gradle testLocal构建并运行src/test/java ,而运行gradle check除了运行默认的android instrumentTest源集之外,还运行这些测试。

Hope this helps! 希望这可以帮助!

Update: Jake Wharton just announced the gradle-android-test-plugin . 更新:杰克沃顿刚刚宣布了gradle-android-test-plugin You can find it at https://github.com/square/gradle-android-test-plugin 您可以在https://github.com/square/gradle-android-test-plugin找到它

It seems to be pretty streamlined, especially if you plan to use robolectric . 它看起来非常精简,特别是如果你打算使用robolectric


Old Answer Below 下面的旧答案

The robolectric-plugin looks promising. robolectric-plugin看起来很有希望。

The sample build.gradle file they provide is : 他们提供的示例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
    }
}

It doesn't seem to work with the Android Gradle plugin version 0.5 but maybe it will soon. 它似乎不适用于Android Gradle插件版本0.5,但也许很快就会出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM