10

All my Unit Test started throwing this error:

No such manifest file: build\intermediates\bundles\debug\AndroidManifest.xml

java.lang.NullPointerException
    at org.robolectric.shadows.ShadowAssetManager.getAndResolve(ShadowAssetManager.java:375)
    at org.robolectric.shadows.ShadowAssetManager.getResourceValue(ShadowAssetManager.java:117)
    at android.content.res.AssetManager.getResourceValue(AssetManager.java)
    at android.content.res.Resources.getValue(Resources.java:1347)
    at android.support.v7.widget.AppCompatDrawableManager.loadDrawableFromDelegates(AppCompatDrawableManager.java:332)
    at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:197)
    at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:190)
    at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(AppCompatDrawableManager.java:711)
    at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:195)
    at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(TintTypedArray.java:81)
    at android.support.v7.app.AppCompatDelegateImplBase.__constructor__(AppCompatDelegateImplBase.java:131)
    at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java)
    at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java)
    at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java)
    at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java)
    at android.support.v7.app.AppCompatDelegateImplV23.<init>(AppCompatDelegateImplV23.java)
    at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:203)
    at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:185)
    at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
    at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:71)
    at android.app.Activity.performCreate(Activity.java:6237)
    at org.robolectric.util.ReflectionHelpers.callInstanceMethod(ReflectionHelpers.java:195)
    at org.robolectric.util.ActivityController$1.run(ActivityController.java:126)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:340)
    at org.robolectric.shadows.CoreShadowsAdapter$2.runPaused(CoreShadowsAdapter.java:40)
    at org.robolectric.util.ActivityController.create(ActivityController.java:123)
    at org.robolectric.util.ActivityController.create(ActivityController.java:133)
    at com.si.play.adapter.RosterAdapter2Test.setUp(RosterAdapter2Test.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:250)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:176)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:142)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)

It worked just fine. The only thing that I changed is that I updated Android Studio to 2.3 and the gradle plugin to 2.3. So far I fix it by manually writing down $MODULE_DIR$ in each test's Run Configuration path. But is really annoying write it down every time. Has anyone experience something like this?

4gus71n
  • 3,717
  • 3
  • 39
  • 66

3 Answers3

11

Set it by default, so every new test configuration that you create will inherit it:

default setting

Run > Edit Configurations... > Defaults > Android JUnit

in Working directory enter: $MODULE_DIR$

Bartek Lipinski
  • 30,698
  • 10
  • 94
  • 132
Eugen Martynov
  • 19,888
  • 10
  • 61
  • 114
  • 1
    Another thing to remember here is that if you try to rerun previously failing test after setting `Working directory` it might still fail because it might have an already existing configuration without `Working directory` (higher in the list in the wndow). Be sure to remove previous JUnit configurations! – Bartek Lipinski Apr 05 '17 at 09:12
0

Android studio is looking at APP folder to run tests from AS 2.3 version. If you have Custom Roboelectric Runner extending RoboelectricTestRunner, you can override the working directory inside that, instead of setting WORKING DIR from edit configurations every time.

Here is my code.

public class CustomRobolectricRunner extends RobolectricTestRunner {

    // Build output location for Android Studio 2.2 and older
    private static final String BUILD_OUTPUT = "build/intermediates";

    // Build output location for Android Studio 2.3 and newer
    private static final String BUILD_OUTPUT_APP_LEVEL = "app/build/intermediates";

    public CustomRobolectricRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override
    protected AndroidManifest getAppManifest(Config config) {
        FileFsFile res = FileFsFile.from(BUILD_OUTPUT, "/res/merged", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
        FileFsFile assets = FileFsFile.from(BUILD_OUTPUT, "assets", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
        FileFsFile manifest = FileFsFile.from(BUILD_OUTPUT, "manifests", "full", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, "AndroidManifest.xml");

        // If above files does not exist in the specified paths, look them at the app folder level. This is needed
        // as Android studio 2.3 changed the working directory.
        if (!manifest.exists()) {
            manifest = FileFsFile.from(BUILD_OUTPUT_APP_LEVEL, "manifests", "full", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, "AndroidManifest.xml");
        }

        if (!res.exists()) {
            res = FileFsFile.from(BUILD_OUTPUT_APP_LEVEL, "/res/merged", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
        }

        if (!assets.exists()) {
            assets = FileFsFile.from(BUILD_OUTPUT_APP_LEVEL, "assets", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
        }

        AndroidManifest androidManifest = new AndroidManifest(manifest, res, assets) {
            @Override
            public Class getRClass() {
                return R.class;
            }

            public int getTargetSdkVersion() {
                /**
                 * Lollipop is currently the highest version supported in 3.0.
                 */
                return Build.VERSION_CODES.LOLLIPOP;
            }
        };

        return androidManifest;
    }
cigien
  • 57,834
  • 11
  • 73
  • 112
0

When someone is facing this issue,for this case, adding this line should help

in "android" brackets

in app/build.gradle

testOptions.unitTests {
    includeAndroidResources = true
}
cigien
  • 57,834
  • 11
  • 73
  • 112
Lucas
  • 458
  • 4
  • 6