I've got a library project using robolectric 3.0 at API21, with com.android.tools.build:gradle:1.3.1
.
I want to use test resources (as if under src/androidTest/res/...
), namely com.mypackage.test.R.java
(as opposed to com.mypackage.R.java
for production) in robolectric tests.
What I have so far:
Directory structure is
src/
main/
java
res
test/
java
// no res here because it's not picked up
androidTest/
res // picked up by androidTest build variant to generate test.R.java
Then in build.gradle:
android {
compileSdkVersion 21
buildToolsVersion = "22.0.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 21
}
sourceSets {
test {
java {
srcDir getTestRJavaDir()
}
}
}
}
def private String getTestRJavaDir(){
def myManifestRoot = (new XmlParser()).parse("${project.projectDir}/src/main/AndroidManifest.xml")
def myPackageNamespace = myManifestRoot.@package
def myPackagePath = myPackageNamespace.replaceAll("\\.", "/")
return "${project.buildDir}/generated/source/r/androidTest/debug/${myPackagePath}/test"
}
afterEvaluate { project ->
[tasks.compileDebugUnitTestSources, tasks.compileReleaseUnitTestSources]*.dependsOn("compileDebugAndroidTestSources")
}
My tests now successfully compile with test.R.java.
However, at runtime, they fail because robolectric now fails to find my asset files, because they are now located in ${project.buildDir}/intermediates/assets/androidTest/debug
whereas previously they were in ${project.buildDir}/intermediates/assets/debug
. My suspicion is that robo would also fail to find resource files because they have also been moved under the androidTest
(build variant?) directory.
So two questions: 1) is there a better way to do this? 2) if there isn't, how can I tell robolectric where to look for the asset files?
I've tried @Config(assetDir="build/intermediates/assets/androidTest/debug")
and @Config(assetDir="../build/intermediates/assets/androidTest/debug")
to no avail.
You can create a custom roboletric test runner like:
public class CustomRobolectricGradleTestRunner extends RobolectricGradleTestRunner {
public CustomRobolectricGradleTestRunner(Class<?> klass) throws InitializationError {
super(klass);
}
// Fix for the NotFound error with openRawResource()
@Override
protected AndroidManifest getAppManifest(Config config) {
String manifest = "src/main/AndroidManifest.xml";
String res = String.format("../app/build/intermediates/res/merged/%1$s/%2$s", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
String asset = "src/test/assets";
return new AndroidManifest(Fs.fileFromPath(manifest), Fs.fileFromPath(res), Fs.fileFromPath(asset));
}
}
In the variable asset you can define something like "../build/intermediates/assets/androidTest/debug"