How to wait for async task in Espresso without IdlingResource
我有以下浓缩咖啡代码:
1
2 3 4 5 6 7 |
@Test fun backgroundWorkDisplaysTextAfterLoading() { onView(withId(R.id.btn_next_fragment)).perform(click()) onView(withId(R.id.btn_background_work)).perform(click()) onView(withId(R.id.hiddenTextView)).check(matches(isDisplayed())) |
当点击btn_background_work时,有一个服务调用会在2秒内返回响应,然后hiddenTextview就会变得可见。
如何让 Espresso 等待执行 ViewAssertion ( check(matches(isDisplayed)) ),直到该服务调用返回一个值?服务调用通过 Retrofit 完成,服务调用在 Schedulers.io() 线程上完成。
我不能接触生产代码,所以在生产代码中实现 IdlingResources 是不可能的。
感谢任何帮助!
使用空闲资源不需要更新生产中的代码。
但这也可以按照您的要求在没有空闲资源的情况下完成,您可以使用此自定义 ViewAction:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
/** * Perform action of waiting until the element is accessible & not shown. * @param viewId The id of the view to wait for. * @param millis The timeout of until when to wait for. */ public static ViewAction waitUntilShown(final int viewId, final long millis) { return new ViewAction() { @Override public Matcher<View> getConstraints() { return isRoot(); } @Override @Override do { uiController.loopMainThreadForAtLeast(50); // timeout happens |
你可以这样使用它:
1
|
onView(isRoot()).perform(waitUntilShown(R.id.hiddenTextView, 5000));
|
如有必要,更新 5 秒(5000 毫秒)的超时时间。
你仍然可以实现
的
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private class ViewPropertyChangeCallback(private val matcher: Matcher<View>, private val view: View) : IdlingResource, ViewTreeObserver.OnDrawListener {
private lateinit var callback: IdlingResource.ResourceCallback override fun getName() ="View property change callback" override fun isIdleNow() = matched override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback) { override fun onDraw() { |
然后创建一个自定义的
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
fun waitUntil(matcher: Matcher<View>): ViewAction = object : ViewAction {
override fun getConstraints(): Matcher<View> { override fun getDescription(): String { override fun perform(uiController: UiController, view: View) { |
并更新您的测试以使用该操作:
1
2 3 4 |
onView(withId(R.id.hiddenTextView)).perform(waitUntil(isDisplayed()))
// or onView(withId(R.id.hiddenTextView)).perform(waitUntil(withEffectiveVisibility(VISIBLE))) .check(matches(isDisplayed())) |
如果没有
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/268982.html