java - 是否可以使用 Espresso 的 IdlingResource 等到某个视图出现?
问题描述
在我的测试中,我有一个阶段,在按下按钮后,应用程序会执行大量异步计算并向云服务发出请求,之后它会显示某个视图。
是否可以使用 Espresso 的IdlingResource
实现等到某个视图出现?
我在这里阅读了答案,评论似乎建议您可以使用IdlingResource
,但我不明白如何。Espresso 似乎没有任何内置方法来处理长操作,但不得不编写自己的等待循环感觉就像是 hack。
有什么方法可以解决这个问题,还是我应该按照链接线程中的答案建议做?
解决方案
Atte Backenhof 的解决方案有一个小错误(或者我可能不完全理解逻辑)。
getView应该返回 null 而不是抛出异常以使 IdlingResources 工作。
这是带有修复程序的 Kotlin 解决方案:
/**
* @param viewMatcher The matcher to find the view.
* @param idleMatcher The matcher condition to be fulfilled to be considered idle.
*/
class ViewIdlingResource(
private val viewMatcher: Matcher<View?>?,
private val idleMatcher: Matcher<View?>?
) : IdlingResource {
private var resourceCallback: IdlingResource.ResourceCallback? = null
/**
* {@inheritDoc}
*/
override fun isIdleNow(): Boolean {
val view: View? = getView(viewMatcher)
val isIdle: Boolean = idleMatcher?.matches(view) ?: false
if (isIdle) {
resourceCallback?.onTransitionToIdle()
}
return isIdle
}
/**
* {@inheritDoc}
*/
override fun registerIdleTransitionCallback(resourceCallback: IdlingResource.ResourceCallback?) {
this.resourceCallback = resourceCallback
}
/**
* {@inheritDoc}
*/
override fun getName(): String? {
return "$this ${viewMatcher.toString()}"
}
/**
* Tries to find the view associated with the given [<].
*/
private fun getView(viewMatcher: Matcher<View?>?): View? {
return try {
val viewInteraction = onView(viewMatcher)
val finderField: Field? = viewInteraction.javaClass.getDeclaredField("viewFinder")
finderField?.isAccessible = true
val finder = finderField?.get(viewInteraction) as ViewFinder
finder.view
} catch (e: Exception) {
null
}
}
}
/**
* Waits for a matching View or throws an error if it's taking too long.
*/
fun waitUntilViewIsDisplayed(matcher: Matcher<View?>) {
val idlingResource: IdlingResource = ViewIdlingResource(matcher, isDisplayed())
try {
IdlingRegistry.getInstance().register(idlingResource)
// First call to onView is to trigger the idler.
onView(withId(0)).check(doesNotExist())
} finally {
IdlingRegistry.getInstance().unregister(idlingResource)
}
}
在您的 UI 测试中使用:
@Test
fun testUiNavigation() {
...
some initial logic, navigates to a new view
...
waitUntilViewIsDisplayed(withId(R.id.view_to_wait_for))
...
logic on the view that we waited for
...
}
重要更新: IdlingResources 的默认超时为 30 秒,它们不会永远等待。要增加超时,您需要在 @Before 方法中调用它,例如:
IdlingPolicies.setIdlingResourceTimeout(3, TimeUnit.MINUTES)
推荐阅读
- webpack - 无需重建即可进入生产阶段
- azure - 使用 az cli 在 azure 中创建文件共享
- c# - 单元测试 - 确保所有存储库都通过构造函数
- c# - 如何在 Root.Master.cs 中获取 EPIServer 当前加载页面的块?
- laravel - 无法获取已设置的 Laravel cookie
- python - 如何修复 OpenSSL.SSL.WantReadError?
- java - 方法代码覆盖率不包括在 Spring Reactor 中调用 flatMap() 的情况
- java - Java 运行时环境内存不足,无法继续进行 elasticsearch
- sql - Exist query Oracle join syntax vs ANSI JOIN syntax
- hibernate - 新的 Spring Boot 应用程序启动失败 Error Creating bean with name 'entityManagerFactory'