我正在使用 Roboletric 运行一些测试,但遇到了一个无法解决的问题。 当我运行测试时,“AndroidManifest”出现以下错误:
警告:在 .\AndroidManifest.xml 中找不到清单文件。
仅退回到 Android 操作系统资源。要删除此警告,请注释 使用 @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]...
在有错误的这一行是以下代码: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());
}
}
在 Robolectric GitHub Issue 上关于此问题的帖子解决了我的问题。
对我有用的答案的方面是在我的模块的testOptions
文件中添加一个
build.gradle
块:
testOptions {
unitTests {
includeAndroidResources = true
}
}
添加此块后,我的测试能够运行并访问字符串资源。
关于舱单位置
也就是说,Android Gradle 插件会合并 AndroidManifest.xml 并将结果放在上述中间目录下。所以src/main/AndroidManifest.xml的内容会影响测试结果。
因此,如果您想在 @Config 中指定清单选项,只需使用 @Config(manifest=“AndroidManifest.xml”) 应该就可以了。如果你想使用备用的AndroidManifest.xml,请将其放在Java资源文件夹中,并根据资源文件夹中的相对路径指定@Config。
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 {
}