Android 仪器化测试找不到主要资源
Android instrumented tests cant find a main resource
我已经为此苦苦思索了一段时间,我取得了一些进展,但我现在很卡住了。
我已经在 src/androidTest/res
中放置了一些 android 资源,并且我在我编写的单元测试中访问了它们。
但是看起来它无法访问 src/main/res
中定义的资源——它们似乎没有内置到构建 .R
中,尽管我可以很好地访问它们在 Android Studio 中(没有编译器投诉)。
这是我的更多设置:
build.gradle:
android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
defaultConfig {
applicationId "com.my.app"
minSdkVersion 15
targetSdkVersion 23
versionName APP_VERSION
versionCode getBuildNumber()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
buildTypes {
debug {
versionNameSuffix "+1-DEBUG"
applicationIdSuffix ".debug"
}
beta {
versionNameSuffix "+1-BETA"
applicationIdSuffix ".beta"
signingConfig signingConfigs.release
}
release {
...
}
}
...
}
一次测试class
import com.my.app.R;
...
public class LaunchActivityTest extends ActivityInstrumentationTestCase2<LaunchActivity> {
...
public LaunchActivityTest() {
super(LaunchActivity.class);
}
@BeforeClass
@Override
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
LaunchActivity launchActivity = getActivity();
// read from file
InputStream inputStream = launchActivity.getResources().openRawResource(
com.my.app.debug.test.R.raw.test_config);
...
}
public void testSetUp() {
...
onView(withId(R.id.username_field)).perform(
typeText(JSONUtils.getString(mJSONConfig, "username")));
我得到 com.my.app.debug.test.R.raw.test_config
运行 的代码很好(没有崩溃),那个文件在 src/androidTest/res/raw/
测试在尝试 onView(withId(R.id.username_field)...
时终止——该 ID 在 src/main/res/layout/activity_launch.xml
中的 LaunchActivity 布局中。
这些测试已经 运行 很多,所以我知道它们有效,一切都在正确的位置。我正在四处移动东西,因为我想在正确的位置获得测试资源。资源不合并?资源 ID 现在可能不匹配吗?
java.lang.NullPointerException
at android.support.test.espresso.core.deps.guava.base.Preconditions.checkNotNull(Preconditions.java:210)
at android.support.test.espresso.action.TypeTextAction.<init>(TypeTextAction.java:67)
at android.support.test.espresso.action.TypeTextAction.<init>(TypeTextAction.java:56)
at android.support.test.espresso.action.ViewActions.typeText(ViewActions.java:363)
at com.my.app.package.stuff.LaunchActivityTest.testSetUp(LaunchActivityTest.java:74)
at java.lang.reflect.Method.invoke(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
编辑
正如公认的答案所指出的那样,我的问题是 NPE,但这就是发生的事情。上面,输入流没有以纯文本形式读取我的资源。我最终不得不更改和使用仪器中的上下文,而不是像这样的 activity:
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
Context context = getInstrumentation().getContext();
// read credentials and org from config file
InputStream inputStream = context.getResources().openRawResource(
com.spatialnetworks.fulcrum.debug.test.R.raw.test_config);
我没有找到它的原因是因为我正在捕获异常并继续前进,因为它是一个单元测试并且该异常不会真正发生......但我错了。
此问题不是缺少名称为 R.id.username_field
的资源。相反,它来自一个空字符串(应该输入的字符串)。
首先尝试检查输入字符串是否不为空。
String json = JSONUtils.getString(mJSONConfig, "username");
assertNotNull(json)
onView(withId(R.id.username_field)).perform(typeText(json));
我已经为此苦苦思索了一段时间,我取得了一些进展,但我现在很卡住了。
我已经在 src/androidTest/res
中放置了一些 android 资源,并且我在我编写的单元测试中访问了它们。
但是看起来它无法访问 src/main/res
中定义的资源——它们似乎没有内置到构建 .R
中,尽管我可以很好地访问它们在 Android Studio 中(没有编译器投诉)。
这是我的更多设置:
build.gradle:
android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
defaultConfig {
applicationId "com.my.app"
minSdkVersion 15
targetSdkVersion 23
versionName APP_VERSION
versionCode getBuildNumber()
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
buildTypes {
debug {
versionNameSuffix "+1-DEBUG"
applicationIdSuffix ".debug"
}
beta {
versionNameSuffix "+1-BETA"
applicationIdSuffix ".beta"
signingConfig signingConfigs.release
}
release {
...
}
}
...
}
一次测试class
import com.my.app.R;
...
public class LaunchActivityTest extends ActivityInstrumentationTestCase2<LaunchActivity> {
...
public LaunchActivityTest() {
super(LaunchActivity.class);
}
@BeforeClass
@Override
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
LaunchActivity launchActivity = getActivity();
// read from file
InputStream inputStream = launchActivity.getResources().openRawResource(
com.my.app.debug.test.R.raw.test_config);
...
}
public void testSetUp() {
...
onView(withId(R.id.username_field)).perform(
typeText(JSONUtils.getString(mJSONConfig, "username")));
我得到 com.my.app.debug.test.R.raw.test_config
运行 的代码很好(没有崩溃),那个文件在 src/androidTest/res/raw/
测试在尝试 onView(withId(R.id.username_field)...
时终止——该 ID 在 src/main/res/layout/activity_launch.xml
中的 LaunchActivity 布局中。
这些测试已经 运行 很多,所以我知道它们有效,一切都在正确的位置。我正在四处移动东西,因为我想在正确的位置获得测试资源。资源不合并?资源 ID 现在可能不匹配吗?
java.lang.NullPointerException
at android.support.test.espresso.core.deps.guava.base.Preconditions.checkNotNull(Preconditions.java:210)
at android.support.test.espresso.action.TypeTextAction.<init>(TypeTextAction.java:67)
at android.support.test.espresso.action.TypeTextAction.<init>(TypeTextAction.java:56)
at android.support.test.espresso.action.ViewActions.typeText(ViewActions.java:363)
at com.my.app.package.stuff.LaunchActivityTest.testSetUp(LaunchActivityTest.java:74)
at java.lang.reflect.Method.invoke(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
编辑 正如公认的答案所指出的那样,我的问题是 NPE,但这就是发生的事情。上面,输入流没有以纯文本形式读取我的资源。我最终不得不更改和使用仪器中的上下文,而不是像这样的 activity:
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
Context context = getInstrumentation().getContext();
// read credentials and org from config file
InputStream inputStream = context.getResources().openRawResource(
com.spatialnetworks.fulcrum.debug.test.R.raw.test_config);
我没有找到它的原因是因为我正在捕获异常并继续前进,因为它是一个单元测试并且该异常不会真正发生......但我错了。
此问题不是缺少名称为 R.id.username_field
的资源。相反,它来自一个空字符串(应该输入的字符串)。
首先尝试检查输入字符串是否不为空。
String json = JSONUtils.getString(mJSONConfig, "username");
assertNotNull(json)
onView(withId(R.id.username_field)).perform(typeText(json));