使用robolectric找不到AndroidManifest.xml

使用robolectric找不到AndroidManifest.xml

错误信息:

java.lang.RuntimeException: build\intermediates\bundles\debug\AndroidManifest.xml not found or not a file; it should point to your project's AndroidManifest.xml

解决方法:

  1. **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这个路径。
    我的项目这两个目录都不存在啊。。。

  2. **只能自己实现该类,复写对应方法。 **
    然后用@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与RobolectricGradleTestRunner的区别,并没有完全搞清楚。不过有一个区别基本明确。RobolectricTestRunner注解时,RuntimeEnvironment.application拿到的是一个原生的application.而RobolectricGradleTestRunner拿到的,是manifest中定义的那个application如果项目中专门定义过application,并在manifest中声明。那么使用上面两个注解的变现形式可能会不同。
  (这也是为什么 3.1例子中使用的是RobolectricTestRunner,因为manifest中定义的那个application中有绑定服务操作,框架不支持)

你可能感兴趣的:(android开发,测试)