错误信息:
java.lang.RuntimeException: build\intermediates\bundles\debug\AndroidManifest.xml not found or not a file; it should point to your project's AndroidManifest.xml
解决方法:
**config指定目录,结果没用,robolectric的bug **
@Config(manifest = “D:/newApp/app/src/main/AndroidManifest.xml”, constants = BuildConfig.class , sdk = 21)
找到源代码,RobolectricGradleTestRunner.java里实现,根本没有通过config来取manifest目录,坑爹。。
private static final String BUILD_OUTPUT = "build/intermediates";
if (FileFsFile.from(BUILD_OUTPUT, "manifests").exists()) {
manifest = FileFsFile.from(BUILD_OUTPUT, "manifests", "full", flavor, type, "AndroidManifest.xml");
} else {
manifest = FileFsFile.from(BUILD_OUTPUT, "bundles", flavor, type, "AndroidManifest.xml");
}
AndroidManifest.xml这个路径是神马,默认是build/intermediates/manifests/full/debug/AndroidManifest.xml,如果这个路径不存在,会查找build/intermediates/bundles/debug/AndroidManifest.xml这个路径。
我的项目这两个目录都不存在啊。。。
**只能自己实现该类,复写对应方法。 **
然后用@RunWith(MyRobolectricTestRunner.class) 替代@RunWith(RobolectricGradleTestRunner.class)
简单粗暴写法:
(根据自己项目目录直接写死好了,但不推荐,最好参照RobolectricGradleTestRunner的实现来写)
public class MyRobolectricTestRunner extends RobolectricGradleTestRunner {
private static final String BUILD_OUTPUT = “D:/newApp/framework/build/intermediates/”;
public CustomTestRunner(Class> testClass) throws InitializationError {
super(testClass);
}
@Override
protected AndroidManifest getAppManifest(Config config) {
String manifestPath = BUILD_OUTPUT + "/merged_manifests/debug/processDebugManifest/merged/AndroidManifest.xml";
String resDir = BUILD_OUTPUT + "res/merged/debug";
String assetsDir = BUILD_OUTPUT + "merged_assets/debug";
AndroidManifest manifest = createAppManifest(Fs.fileFromPath(manifestPath),
Fs.fileFromPath(resDir),
Fs.fileFromPath(assetsDir),"com.tencent.framework");
return manifest;
}
}
参考RobolectricGradleTestRunner实现写:
public class MyRobolectricTestRunner extends RobolectricGradleTestRunner {
private static final String BUILD_OUTPUT = "build/intermediates";
public CustomTestRunner(Class> klass) throws InitializationError {
super(klass);
}
@Override
protected AndroidManifest getAppManifest(Config config) {
final FileFsFile res;
final FileFsFile assets;
final FileFsFile manifest;
if (FileFsFile.from(BUILD_OUTPUT, "res", "merged","debug").exists()) {
res = FileFsFile.from(BUILD_OUTPUT, "res", "merged", "debug");
} else {
res = FileFsFile.from(BUILD_OUTPUT, "res", "merged", "release");
}
if (FileFsFile.from(BUILD_OUTPUT, "merged_assets","debug").exists()) {
assets = FileFsFile.from(BUILD_OUTPUT, "merged_assets", "debug");
} else {
assets = FileFsFile.from(BUILD_OUTPUT, "merged_assets", "release");
}
if (FileFsFile.from(BUILD_OUTPUT, "merged_manifests","debug","processDebugManifest","merged").exists()) {
manifest = FileFsFile.from(BUILD_OUTPUT, "merged_manifests","debug","processDebugManifest","merged", "AndroidManifest.xml");
} else {
manifest = FileFsFile.from(BUILD_OUTPUT, "merged_manifests","release","processReleaseManifest","merged", "AndroidManifest.xml");
}
String packageName = "com.xxx.xxx";//这里后面要改一下,要不测试app目录就会有问题
return new AndroidManifest(manifest, res, assets, packageName);
}
}
备注:用RobolectricGradleTestRunner,就会报找不到AndroidManifest.xml,而用只要用RobolectricestRunner 就不会报该错误。
在大部分场景下,在测试类前的注解声明,建议还是使用RobolectricGradleTestRunner。
RobolectricTestRunner与RobolectricGradleTestRunner的区别,并没有完全搞清楚。不过有一个区别基本明确。RobolectricTestRunner注解时,RuntimeEnvironment.application拿到的是一个原生的application.而RobolectricGradleTestRunner拿到的,是manifest中定义的那个application如果项目中专门定义过application,并在manifest中声明。那么使用上面两个注解的变现形式可能会不同。
(这也是为什么 3.1例子中使用的是RobolectricTestRunner,因为manifest中定义的那个application中有绑定服务操作,框架不支持)