我正在尝试将我的 Robolectric 测试与新的 Gradle Android 构建系统一起运行,但我无法访问我的主项目的资源。
为了避免 java
和 android
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
我在 test/
中的 build.gradle
目前看起来像这样:
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'
...
}
邪恶的类路径黑客允许我访问我的主项目的所有类,除了 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
必须有更好的方法来使用新的构建系统执行 Robolectric 测试,对吧?
最佳答案
我遇到了同样的问题,这就是我想出的。我没有为测试创建单独的项目,而是为 Robolectric 测试创建了一个源集,并添加了一个“检查”将依赖的新任务。使用您问题中的一些代码,以下是(工作)构建文件的相关位:
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
我已经包含了我的依赖项 block ,以指出为了让我能够顺利进行,我必须在我的自定义 testLocal中重复我的所有
源集。compile
依赖项
运行 gradle testLocal
只构建和运行 src/test/java
内部的测试,而运行 gradle check
还会运行这些测试到默认的 android instrumentTest 源集中的那些。
希望这会有所帮助!
关于android - 使用 Gradle 的 Robolectric : Resources not found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16649397/