【问题标题】:Android Espresso doesn't wait for fragments to loadAndroid Espresso 不等待片段加载
【发布时间】:2017-04-01 04:07:16
【问题描述】:

我刚刚开始使用 Espresso 来测试 Android 应用,但遇到了一些问题。我有一个带有按钮的 Activity,它以通常的方式替换片段:

public void onClick(View v) {
    final FragmentTransaction t = getFragmentManager().beginTransaction();
    t.setCustomAnimations(R.animator.fragment_slide_in_up, 0);
    t.replace(R.id.fragment_container,
        LogInFragment.newInstance(), LogInFragment.TAG)
        .addToBackStack(LogInFragment.TAG);
    t.commit();
}

在我的测试中,我单击发送新片段的按钮,然后检查新片段是否可见。

onView(withId(R.id.login_btn))
    .perform(click());
Thread.sleep(500);
onView(withId(R.id.email_input))
    .check(matches(isDisplayed()));

如果我从测试中删除Thread.sleep(),即使我从活动代码中删除setCustomAnimations(),测试也会失败。

按照说明,我手机上的所有动画都已关闭。我的理解是 Espresso 知道 UI 线程状态,并会等到一切准备就绪。但是如果我做一个onView(withId(R.id.widgetOnNewFragment)),它每次都会爆炸。每次显示新片段时,我都需要添加Thread.sleep(500)

我错过了什么吗?我想我不应该在我的测试代码中添加几十个 Thread.sleep() 。

【问题讨论】:

标签: android android-espresso


【解决方案1】:

虽然 Espresso 框架“等待”某些主 UI 线程活动,但动画需要 IdlingResource 方法(正如 Honza 建议的那样)。

在这个概念上有good tutorials,甚至detailed implementations

实际上,由于动画很少会影响 UI 的功能测试,因此大多数开发人员都会禁用动画。 IMO,这是anti-pattern,因为它没有映射到真实的用户体验(大多数人购买手机并使用默认设置)。这是您必须自己做出的决定。如果你想将动画作为你的功能需求的一部分,有ways,但它需要你重新实现和重写你的测试。

【讨论】:

  • 那么做一个fragmentTransaction.replace()总是一个动画,总是需要一个IdlingResource?
  • 是的。我的经验是 fragmentTransaction.commit() 与主线程异步,并且不会阻止 Espresso 执行。您是否尝试过 .commitNow()?该文档在此处讨论了 FragmentTransaction 使用的异步性质:developer.android.com/reference/android/app/…
  • 删除动画是一种反模式,但如果最终测试是人为的,那不是问题。我发现添加一层非自动化测试很有用,我可以在其中感受到用户与应用程序的交互,并发现一些自动化测试不容易检测到的故障。
  • 为了测试目的而修改 prod 代码也是一种反模式 imo
猜你喜欢
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
相关资源
最近更新 更多