android - Espresso 不会等到显示对话框并失败

标签 android android-espresso

我正在使用 Espresso 进行一些简单的测试。其中之一是关于单击 View 并检查是否显示对话框。

我的问题是有时有效,有时无效。只有当我在检查对话框之前 sleep 时,它才会始终有效。有没有不使用 sleep 的解决方案?

这是我的代码(非常简单):

onView(withId(R.id.forgot_password)).perform(click());
// only works if use Thread.sleep(ms) here
onView(withText(R.string.reset_password)).check(matches(isDisplayed()));

编辑:

我正在展示与静态助手的对话,但简化是这样的。而且我没有在中间执行任何后台任务。

最终的 TextInputDialog textInputDialog = new

TextInputDialog.Builder(context)
                .setTitle(titleId)
                .setInputType(inputType)
                .setHint(hintId)
                .setPreFilledText(preFilledText)
                .setNegativeButton(R.string.cancel, null)
                .setPositiveButton(positiveButtonId, onTextSubmittedListener)
                .create();
textInputDialog.show(textInputDialog);

谢谢!

最佳答案

在某些情况下禁用动画是不可能的,例如:

  • 在云设备上运行测试时。 Firebase 测试实验室不允许更改设备配置
  • 当您等待某个后台线程更新用户界面时,例如 http 响应。

在这些情况下,最简单的方法就是等待元素显示。方法如下:

简单的助手:

class WaifForUIUpdate {

public static void waifForWithId(@IdRes int stringId) {
    
    ViewInteraction element;
    do {
        waitFor(500);

        //simple example using withText Matcher.
        element = onView(withText(stringId));

    } while (!MatcherExtension.exists(element));

}

static void waitFor(int ms) {
    final CountDownLatch signal = new CountDownLatch(1);

    try {
        signal.await(ms, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        Assert.fail(e.getMessage());
    }
}
}

匹配器 来自 twisterrob

public class MatcherExtension {
 @CheckResult
    public static boolean exists(ViewInteraction interaction) {
        try {
            interaction.perform(new ViewAction() {
                @Override
                public Matcher<View> getConstraints() {
                    return any(View.class);
                }

                @Override
                public String getDescription() {
                    return "check for existence";
                }

                @Override
                public void perform(UiController uiController, View view) {
                    // no op, if this is run, then the execution will continue after .perform(...)
                }
            });
            return true;
        } catch (AmbiguousViewMatcherException ex) {
            // if there's any interaction later with the same matcher, that'll fail anyway
            return true; // we found more than one
        } catch (NoMatchingViewException ex) {
            return false;
        } catch (NoMatchingRootException ex) {
            // optional depending on what you think "exists" means
            return false;
        }
    }

}

用法:

WaifForUIUpdate.waifForWithId(R.string.some_string);
//now do your validations

关于android - Espresso 不会等到显示对话框并失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42766596/

相关文章:

android - ImageView 上的透明 View

java - 从 BroadcastReceiver 启动 Activity

java - Espresso 点击菜单项

android - 如何查看 Android Orchestrator 日志?

android - 运行 espresso 测试时测试仪器进程崩溃

android - 使用 React Native 录制 Espresso 测试

java - 一种在 TextView 中更改文本时间的方法?

android - 如何使用 HttpURLConnection 而不是 Volley 获取 JSON 对象?

android - Nexus one 等更大分辨率手机的布局问题?

java - 如何在 Espresso 中等待异步事件?