使用Espresso在Android上测试进度条

Chr*_*sco 16 android android-espresso

工作流程应如下:

  1. 活动开始
  2. 进度条可见
  3. 网络请求触发(空闲资源已经注册,因此espresso知道如何等待它).
  4. 进度条被隐藏
  5. 显示来自网络的文本.

到目前为止,我已经为第1,3,5步编写了断言,它完美地运行:

onView(withText("foo 1"))
    .check(matches(isDisplayed()));
Run Code Online (Sandbox Code Playgroud)

问题是,我不知道如何让espresso知道在请求发出之前和发出请求之后验证进度条的可见性.

考虑onCreate()方法如下:

super.onCreate(...);
setContentView(...);

showProgressBar(true);
apiClient.getStuff(new Callback() {
    public void onSuccess() {
        showProgressBar(false);
    }
});
Run Code Online (Sandbox Code Playgroud)

我尝试了以下但它不起作用:

// Activity is launched at this point.
activityRule.launchActivity(new Intent());

// Up to this point, the request has been fired and response was 
// returned, so the progress bar is now GONE.
onView(withId(R.id.progress_bar))
   .check(matches(isDisplayed()));

onView(withId(R.id.progress_bar))
    .check(matches(not(isDisplayed())));
Run Code Online (Sandbox Code Playgroud)

发生这种情况的原因是,由于客户端被注册为空闲资源,espresso将在运行第一个之前等待它再次空闲,onView(...progressbar...)...因此我需要一种方法让espresso知道进入空闲状态之前运行.

编辑:这也不起作用:

idlingResource.registerIdleTransitionCallback(new IdlingResource.ResourceCallback() {
        @Override
        public void onTransitionToIdle() {
            onView(withId(R.id.progress_bar))
                    .check(matches(isDisplayed()));
        }
    });
Run Code Online (Sandbox Code Playgroud)

Mat*_*ers 13

Espresso有动画问题.你可以将进度条的drawable设置为静态的,仅用于测试,它可以按预期工作.

Drawable notAnimatedDrawable = ContextCompat.getDrawable(getActivity(), R.drawable.whatever);
((ProgressBar) getActivity().findViewById(R.id.progress_bar)).setIndeterminateDrawable(notAnimatedDrawable);

onView(withId(R.id.progress_bar)).check(matches(isDisplayed()));
Run Code Online (Sandbox Code Playgroud)

  • 禁用动画似乎可以解决 Android 7 上的问题,但不适用于 Android 6 及更早版本。 (2认同)

riw*_*nyk 5

正如我所看到的,Espresso它与跳过动态UI操作紧密相关,这就是为什么您不能ProgressBar使用测试的原因Espresso。但是,您可以使用另一个Android Google工具轻松完成此操作UiAutomator

    saveButton().click(); // perform action opening ProgressBar with UiAutomator, not Espresso
    assertTrue(progressBar().exists());
Run Code Online (Sandbox Code Playgroud)

使用这些静态工具:

public static UiObject progressBar() {
    return uiObjectWithText(R.string.my_progress);
}

public static UiObject saveButton() {
    return uiObjectWithId(R.id.my_save_button);
}

public static UiObject uiObjectWithId(@IdRes int id) {
    String resourceId = getTargetContext().getResources().getResourceName(id);
    UiSelector selector = new UiSelector().resourceId(resourceId);
    return UiDevice.getInstance(getInstrumentation()).findObject(selector);
}

public static UiObject uiObjectWithText(@StringRes int stringRes) {
    UiSelector selector = new UiSelector().text(getTargetContext().getString(stringRes));
    return UiDevice.getInstance(getInstrumentation()).findObject(selector);
}
Run Code Online (Sandbox Code Playgroud)

确保您build.gradle包括:

androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
Run Code Online (Sandbox Code Playgroud)