ProgressBars和Espresso

时间:2015-10-22 19:30:07

标签: android android-espresso

当我在运行一些espresso测试时显示的布局中有ProgressBar时,我遇到了:

Caused by: android.support.test.espresso.AppNotIdleException: Looped for 1670 iterations over 60 SECONDS. The following Idle Conditions failed .

解决这个问题的好方法是什么?找到一些hackish东西,但寻找一个很好的方式

5 个答案:

答案 0 :(得分:13)

如果在测试开始时ProgressBar不可见,则Drawable可以由自定义ViewAction替换:

// Replace the drawable with a static color
onView(isAssignableFrom(ProgressBar.class)).perform(replaceProgressBarDrawable());

// Click a button (that will make the ProgressBar visible)
onView(withText("Show ProgressBar").perform(click());

自定义ViewAction

public static ViewAction replaceProgressBarDrawable() {
    return actionWithAssertions(new ViewAction() {
        @Override
        public Matcher<View> getConstraints() {
            return isAssignableFrom(ProgressBar.class);
        }

        @Override
        public String getDescription() {
            return "replace the ProgressBar drawable";
        }

        @Override
        public void perform(final UiController uiController, final View view) {
            // Replace the indeterminate drawable with a static red ColorDrawable
            ProgressBar progressBar = (ProgressBar) view;
            progressBar.setIndeterminateDrawable(new ColorDrawable(0xffff0000));
            uiController.loopMainThreadUntilIdle();
        }
    });
}

答案 1 :(得分:7)

我有同样的问题。我无法找到一个完全优雅的解决方案,但我也会发布我的方法。

我尝试做的是覆盖ProgressBar上的indeterminateDrawable。当有一个简单的drawable时,没有动画发生,并且Espresso测试没有遇到空闲问题。

不幸的是,mainandroidTest被视为相同。我没有找到覆盖ProgressBar样式的方法。

现在最终结合了https://gist.github.com/Mauin/62c24c8a53593c0a605e#file-progressbar-javaHow to detect whether android app is running UI test with Espresso的一些想法。

首先,我创建了自定义ProgressBar类,一个用于调试,一个用于发布。发布版本只调用超级构造函数而不执行任何其他操作。调试版本会覆盖方法setIndeterminateDrawable。有了这个,我可以设置一个简单的drawable而不是动画。

发布代码:

public class ProgressBar extends android.widget.ProgressBar {

  public ProgressBar(Context context) {
    super(context);
  }

  public ProgressBar(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
  }

}

调试代码:

public class ProgressBar extends android.widget.ProgressBar {

  public ProgressBar(Context context) {
    super(context);
  }

  public ProgressBar(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
  }

  @SuppressWarnings("deprecation")
  @Override
  public void setIndeterminateDrawable(Drawable d) {
    if (isRunningTest()) {
        d = getResources().getDrawable(R.drawable.ic_replay);
    }
    super.setIndeterminateDrawable(d);
  }

  private boolean isRunningTest() {
    try {
        Class.forName("base.EspressoTestBase");
        return true;
    } catch (ClassNotFoundException e) {
        /* no-op */
    }
    return false;
  }

}

正如您所看到的,我还添加了检查我的应用程序是否正在运行Espresso测试,而我正在搜索的课程是我的Espresso测试的基础。

糟糕的是,您必须更新所有代码才能使用自定义ProgressBar。但好处是您的发布代码对此解决方案没有重大影响。

答案 2 :(得分:7)

我有类似的问题。早在第一次调用getActivity()时测试就失败了。因此,在活动开始后,必须更换ProgressBar的不确定drawable。

$this->session->handler

答案 3 :(得分:2)

基于Thomas R. solution,另一种方法是在测试中更改ProgressBar的drawable,以避免修改生产代码。

示例:

    Activity activity = startActivity();

    // override progress bar infinite animation with a simple image
    ProgressBar progressBar = (ProgressBar) activity.findViewById(R.id.loading_progressbar);
    progressBar.setIndeterminateDrawable(activity.getDrawable(android.R.drawable.ic_lock_lock));

    // click on the button that triggers the display of the progress bar
    onView(withId(R.id.login_button)).perform(click());

答案 4 :(得分:1)

这个答案可能会迟到。使用浓缩咖啡,您必须关闭动画。

  

在您的设备上,在设置&gt;下;开发人员选项,禁用   以下3种设置:

     

窗口动画比例,过渡动画比例,动画持续时间比例

https://developer.android.com/training/testing/espresso/setup.html#set-up-environment

riwnodennyk在Testing progress bar on Android with Espresso有一个答案

但要对UIAnimator持谨慎态度

  

警告:我们建议仅在使用UI Automator时测试您的应用   您的应用必须与系统交互才能完成关键用例。   因为UI Automator与系统应用程序和UI交互,所以您需要   每次系统更新后重新运行并修复UI Automator测试。这样   更新包括Android平台版本升级和新版本   Google Play服务。作为使用UI Automator的替代方案,我们   建议添加密封测试或将您的大型测试分成一个   一套中小型测试。特别是,专注于测试一个   一次进行应用程序间通信,例如发送   信息到其他应用程序并响应意图结果。该   Espresso-Intents工具可以帮助您编写这些较小的测试。

https://developer.android.com/training/testing/fundamentals.html#large-tests