我有一个检查多个条件并在满足时调用另一个活动的方法。当一个条件不满足时,它应该显示一个错误对话框(该对话框目前使用DialogFragment显示警报对话框)。这个方法大致如下:
void checkAndCall() {
CustomObject o1 = null;
try {
o1 = CustomObject.parse(editText1.getText().toString());
} catch (CustomException e) {
handleBadCase(e);
return;
}
CustomObject o2 = null;
try {
o2 = CustomObject.parse(editText2.getText().toString());
} catch (CustomException e) {
handleBadCase(e);
return;
}
callOtherActivity();
}
很不幸,我忘记添加一个返回语句,导致方法掉到下一项检查(失败了),并显示了两个错误对话框。为了确保这种情况不再发生,我写了一个测试。
我的测试看起来像这样:
public class TestClass {
@Rule
public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class);
@Test
public void onlyOneDialogAppearsWithEmptySolve() {
/* Hit solve with no text entered */
onView(withId(R.id.solve_button)).perform(click());
/* Check that dialog is displayed */
onView(isRoot()).inRoot(isDialog()).check(matches(isDisplayed()));
/* Press cancel */
onView(withText(getString(R.string.cancel))).perform(click());
/* No dialog is displayed */
onView(isRoot()).inRoot(isDialog()).check(doesNotExist());
}
}
我原本以为 onView(isRoot()).inRoot(isDialog())
会匹配任何对话框的根视图。 但是,如果它找不到匹配项,它似乎只会挂起。因此,当测试应该满足时(只显示一个对话框并取消),它会挂起。如果我们注释掉那一行,并且不显示任何对话框,则测试会在 检查对话框是否显示 行上挂起。
我不想根据对话框文本进行匹配,因为它们可能都不同。 我仍然需要确保只有一个出现(如果有)。 现在,我利用了所有对话框都有“取消”按钮来进行匹配。 但是,我希望不要依赖于这一点。
是否有一种方法可以说 是否显示任何对话框? 和 没有对话框显示吗? 为什么我的检查会导致挂起?
onView(isRoot()).inRoot(isDialog()).noActivity()
代替doesNotExist()
。这样做可以使代码更加通俗易懂,而不改变原意。 - MoinkhaninRoot
一起使用时,似乎check(doesNotExist())
不起作用,(2) 没有简单的方法来检查一个视图是否在对话框内(而isDialog
匹配一个Root
(Espresso 内部类)而不是一个View
,并使用一些反射来访问一些私有隐藏字段来执行其逻辑)。我知道你说你想避免这种情况,但老实说,最好的方法就是匹配对话框内的某个已知元素。例如,我正在使用AlertDialog
,所以我使用onView(withId(android.R.id.button1)).check(doesNotExist())
。 - Adam BurleyisPlatformPopup
,我发现如果省略inRoot
,针对已知视图的匹配“不存在”即使窗口可见也会通过。在某些情况下,Espresso 仅当指定了inRoot
时才匹配非标准根中的视图。为了解决这个问题,最终我不得不编写一个 try-catch 并捕获NoMatchingRootException
,这仍然会导致线程阻塞,但是这是唯一有效的解决方案。 - Adam Burley