Robolectric with Gradle:找不到资源
我试图与新的Gradle Android构建系统一起运行我的Robolectric测试,但是我一直在访问我的主项目的资源。Robolectric with Gradle:找不到资源
我分裂构建成两个独立的项目,以避免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
我build.gradle
在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'
...
}
邪恶的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
必须有新的编译系统执行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
我包括我的相关模块指出的是,为了让我得到这个并去,我不得不在我的自定义testLocal
源集中重复我所有的compile
依赖关系。
运行gradle testLocal
构建并运行src/test/java
里面的测试,而运行gradle check
除了那些默认的android instrumentTest源集之外还运行这些测试。
希望这有助于!
这看起来像是朝着正确方向迈出的巨大一步,谢谢! Robolectric testrunner正在执行,但是,当任何尝试访问资源时,我现在都会收到“android.content.res.Resources $ NotFoundException:unknown resource xxx”。完整堆栈跟踪这里:https://gist.github.com/passy/255bbd42ada11ad5fba7 – passy
这似乎来自TestRunner的是找不到'AndroidManifest.xml',它位于'SRC/main'。我想我可以在RobolectricTestRunner子类中设置这些路径,但对于Eclipse,我只需将工作目录设置为主项目。我可以在gradle文件中做到这一点吗? – passy
@passy不幸的是我没有看到这个问题出现。但是,你应该能够把你的'AndroidManifest.xml'在项目的根目录下,并覆盖清单源在'build.gradle'做类似于这样设置:'Android版{ sourceSets { 主要{ manifest.srcFile '的AndroidManifest.xml'}}}'资料来源:http://tools.android.com/tech-docs/new-build-system/user-guide – user2457888
更新: 杰克沃顿刚刚宣布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
}
}
它似乎并不与Android摇篮插件版本0.5工作,但也许它会很快。
我焦急地等待Jake的插件来支持由buildType分割的资源。目前似乎无法解决这个问题。有人写了一个补丁来解决这个问题(几个月前),但没有评论,也没有被接受。在此之前,接受答案中的方法正在起作用。 –
似乎像杰克沃顿的插件现在已被弃用? – Flame
是的。似乎有一个转向标准的android测试基础设施的乱舞。 Robolectric对于某些情况仍然有帮助,但是我发现管理应用程序更容易,因此我的大多数纯Java类都是java库模块,它们都是通过junit和Android测试框架对Android进行单元测试的。 –
我不认为这是行得通的。在robolectric中还有一些其他内部的东西,在哪里可以找到哪些实际的资源无法工作(或通过依赖关系来扩展)以及gradle插件的功能。 我需要与Robolectric开发人员合作才能兼容。这是我要做的事情清单。 –
感谢您的输入,@Xav。 – passy
那么还有没有在新的Android Studio IDE中使用gradle运行robolectric的方法? – Imanol