Espresso检查是否没有对话框显示

13

我有一个检查多个条件并在满足时调用另一个活动的方法。当一个条件不满足时,它应该显示一个错误对话框(该对话框目前使用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()) 会匹配任何对话框的根视图。 但是,如果它找不到匹配项,它似乎只会挂起。因此,当测试应该满足时(只显示一个对话框并取消),它会挂起。如果我们注释掉那一行,并且不显示任何对话框,则测试会在 检查对话框是否显示 行上挂起。

我不想根据对话框文本进行匹配,因为它们可能都不同。 我仍然需要确保只有一个出现(如果有)。 现在,我利用了所有对话框都有“取消”按钮来进行匹配。 但是,我希望不要依赖于这一点。

是否有一种方法可以说 是否显示任何对话框?没有对话框显示吗? 为什么我的检查会导致挂起?


5
请尝试使用onView(isRoot()).inRoot(isDialog()).noActivity()代替doesNotExist()。这样做可以使代码更加通俗易懂,而不改变原意。 - Moinkhan
@Moinkhan,这个解决方案对我很有帮助,谢谢。 - Louis
4
@Moinkhan 当对话框存在(未关闭)时,它不会失败。 - fikr4n
这是一个问题的完美风暴,(1) 当与 inRoot 一起使用时,似乎 check(doesNotExist()) 不起作用,(2) 没有简单的方法来检查一个视图是否在对话框内(而 isDialog 匹配一个 Root(Espresso 内部类)而不是一个 View,并使用一些反射来访问一些私有隐藏字段来执行其逻辑)。我知道你说你想避免这种情况,但老实说,最好的方法就是匹配对话框内的某个已知元素。例如,我正在使用 AlertDialog,所以我使用 onView(withId(android.R.id.button1)).check(doesNotExist()) - Adam Burley
注意:对于其他根,例如 isPlatformPopup,我发现如果省略 inRoot,针对已知视图的匹配“不存在”即使窗口可见也会通过。在某些情况下,Espresso 仅当指定了 inRoot 时才匹配非标准根中的视图。为了解决这个问题,最终我不得不编写一个 try-catch 并捕获 NoMatchingRootException,这仍然会导致线程阻塞,但是这是唯一有效的解决方案。 - Adam Burley
https://dev59.com/_5vga4cB1Zd3GeqPzkrj#73894325 - Adam Burley
1个回答

0

由于这是条件/导航逻辑,我会将其放入ViewModel中,并在单元测试中进行测试。使用模拟框架(例如mockito),您可以验证某些方法仅被调用一次。虽然不完全回答了您的问题,但应该有助于避免一些不必要的调用错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接