Robolectric:“未找到AndroidManifest.xml”和"无法找到资源ID#0x7f09001b"

时间:2017-11-23 13:29:02

标签: android compiler-errors android-manifest robolectric

我正在使用Roboletric运行一些测试,但我遇到了一个我无法解决的问题。 当我运行测试时," AndroidManifest":

会出现以下错误
  

警告:在。\ AndroidManifest.xml中找不到清单文件。

     

仅回退到Android OS资源。要删除此警告,请注释   你的测试类是@Config(manifest = Config.NONE)。

     

没有这样的清单文件:。\ AndroidManifest.xml

我已尝试过失败

的解决方案
@Config (manifest = Config.DEFAULT_MANIFEST_NAME)

@Config(manifest = Config.NONE, constants = BuildConfig.class, sdk = 26)

@Config( constants = BuildConfig.class, manifest="src/main/AndroidManifest.xml", sdk = 26 )

执行期间的另一个错误是:

  

android.content.res.Resources $ NotFoundException:无法找到   包中的资源ID#0x7f09001b [android,org.robolectric.default]

...

  

at

     

com.example.robertoassad.alltestsmerge.MainActivity.onCreate(MainActivity.java:52)

这行有错误的行是以下代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

具体setContentView(R.layout.activity_main);

对我来说,我在这个问题上看不出来......

详情:

  • 测试类位于文件夹:app\src\test\java\com\example\robertoassad

  • 测试是: @RunWith( RobolectricTestRunner.class) public class Roboletric { @Test public void clickingLogin_shouldStartLoginActivity() { MainActivity activity = Robolectric.setupActivity(MainActivity.class); activity.findViewById(R.id.button2).performClick();

            Intent expectedIntent = new Intent(activity, SecondActivity.class);
            Intent actual = ShadowApplication.getInstance().getNextStartedActivity();
            assertEquals(expectedIntent.getComponent(), actual.getComponent());
         }
    

    }

3 个答案:

答案 0 :(得分:4)

我遇到了类似的问题。 Robolectric GitHub问题上的post by jongerrish解决了这个问题。

对我有用的答案是在我的模块的function hitung2(obj) { var $row = $(obj).closest('.row'); var a = $row.find(".tt1").val(); var b = $row.find(".tt2").val(); var c = $row.find(".tt3").val(); ntt = (parseInt(a) + parseInt(b) + parseInt(c)) /3; ntt = ntt.toFixed(2); $row.find(".ntt").val(ntt); var d = $row.find(".ntt").val(); var e = $row.find(".np").val(); f = (parseInt(e)*3 + parseInt(d)*7) /10 $row.find(".na").val(f); } <table class="table table-hover"> <tr> <th>No</th> <th>NAMA</th> <th>TOTAL HADIR</th> <th>TT 1</th> <th>TT 2</th> <th>TT 3</th> <th>N.RATA"</th> <th>N.PARTISIPASI</th> <th>N.AKHIR</th> </tr> <?php if(isset($ambil_data)>0){$i=1; foreach($ambil_data as $row) { ?> <tr class="row"> <td><?php echo $i; ?></td> <td><?php echo $row->nama; ?></td> <td><input type="text" class="form-control jml_hadir" id="jml_hadir_<?php echo $i; ?>" maxlength="1" name="jml_hadir" placeholder="Hadir" /><?php echo form_error('jml_hadir'); ?></td> <td><input type="text" class="form-control tt1" id="tt1_<?php echo $i; ?>" placeholder="TT1" maxlength="5" name="tt1" onkeyup="hitung2(this)" /><?php echo form_error('tt1'); ?></td> <td><input type="text" class="form-control tt2" id="tt2_<?php echo $i; ?>" placeholder="TT1" maxlength="5" name="tt2" onkeyup="hitung2(this)" /><?php echo form_error('tt2'); ?></td> <td><input type="text" class="form-control tt3" id="tt3_<?php echo $i; ?>" placeholder="TT1" maxlength="5" name="tt3" onkeyup="hitung2(this)" /><?php echo form_error('tt3'); ?></td> <td><input type="text" class="form-control ntt" id="ntt_<?php echo $i; ?>" name="ntt" readonly /></td> <td><input type="text" class="form-control np" id="np_<?php echo $i; ?>" placeholder="N.Partisipasi" name="np" onkeyup="hitung2(this)"/><?php echo form_error('np'); ?></td> <td><input type="text" class="form-control na" id="na_<?php echo $i; ?>" name="na" readonly /></td> </tr> <?php $i++;}}?> </form> </table> 文件中添加testOptions块:

build.gradle

添加此块后,我的测试能够运行并访问String资源。

答案 1 :(得分:2)

这个问题困扰了我一段时间,这是我的测试代码中的注释。

关于清单位置

使用Gradle构建系统,Robolectric按以下顺序查找AndroidManifest.xml。

  • Java资源文件夹

  • build / intermediates / manifests / [full or fast-start] / [build-type]

因此,根据源代码文件夹组织(例如src / main / AndroidManifest.xml)指定AndroidManifest.xml的位置是一个常见错误。指定的AndroidManifest.xml位置也会影响Robolectric查找合并资源的方式。因此,如果在测试中找不到某些资源,则可能是由于AndroidManifest.xml位置的设置不正确。

也就是说,Android Gradle插件合并AndroidManifest.xml并将结果放在上面提到的中间目录下。因此src / main / AndroidManifest.xml的内容会影响测试结果。

因此,如果你想在@Config中指定manifest选项,那么使用@Config(manifest =“AndroidManifest.xml”)应该没问题。如果要使用备用AndroidManifest.xml,请将其放在Java资源文件夹中,并根据resources文件夹中的相对路径指定@Config。

答案 2 :(得分:0)

从app测试我的库模块时,我也遇到了同样的问题。现在我的收件人和服务都在我的库中,所以为了测试这些,我必须实现自定义测试类,所以Roboelectric可以指向我的库清单而不是应用程序清单:

import android.os.Build;
import org.junit.runners.model.InitializationError;
import org.robolectric.manifest.AndroidManifest;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.res.Fs;

import java.io.File;
import java.io.IOException;

public class RobolectricGradleTestRunner extends RobolectricTestRunner {
    private static final String PROJECT_DIR =
            "C:/MyProject/";


    private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC =
            Build.VERSION_CODES.JELLY_BEAN_MR2;

    public RobolectricGradleTestRunner(final Class<?> testClass) throws Exception {
        super(testClass);
    }

    private static AndroidManifest getAndroidManifest() {

        String manifestPath = PROJECT_DIR+"/src/main/AndroidManifest.xml";
        String resPath = PROJECT_DIR+"/src/main/res";
        String assetPath = PROJECT_DIR+"/src/main/assets";

        System.out.print("manifest path: "+manifestPath);
        System.out.print("resPath path: "+resPath);
        System.out.print("assetPath path: "+assetPath);

        return new AndroidManifest(
                Fs.fileFromPath(manifestPath), Fs.fileFromPath(resPath), Fs.fileFromPath(assetPath)) {
            @Override public int getTargetSdkVersion() {
                return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
            }
        };
    }

    private static String getProjectDirectory() {
        String path = "";
        try {
            File file = new File("..");
            path = file.getCanonicalPath();
            path = path + "/app/";
        } catch (IOException ex) {}
        return path;
    }

    @Override public AndroidManifest getAppManifest(Config config) {
        return getAndroidManifest();
    }
}

并在您的测试类中使用它,如:

@RunWith(RobolectricGradleTestRunner.class)
public class MyClassChangeTest {
}