我使用以下空闲资源实现来等待元素出现在屏幕上,然后再执行检查。
private class ViewPropertyChangeCallback(private val matcher: Matcher<View>, private val view: View) : IdlingResource, ViewTreeObserver.OnDrawListener {
private lateinit var callback: IdlingResource.ResourceCallback
private var matched = false
override fun getName() = "View property change callback"
override fun isIdleNow() = matched
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback) {
this.callback = callback
}
override fun onDraw() {
matched = matcher.matches(view)
callback.onTransitionToIdle()
}
}
fun waitUntil(matcher: Matcher<View>): ViewAction = object : ViewAction {
override fun getConstraints(): Matcher<View> {
return Matchers.any(View::class.java)
}
override fun getDescription(): String {
return StringDescription().let {
matcher.describeTo(it)
"wait until: $it"
}
}
override fun perform(uiController: UiController, view: View) {
if (!matcher.matches(view)) {
ViewPropertyChangeCallback(matcher, view).run {
try {
IdlingRegistry.getInstance().register(this)
view.viewTreeObserver.addOnDrawListener(this)
uiController.loopMainThreadUntilIdle()
} finally {
view.viewTreeObserver.removeOnDrawListener(this)
IdlingRegistry.getInstance().unregister(this)
}
}
}
}
}
fun waitForElement(matcher: Matcher<View>) {
onView(isRoot())
.perform(waitUntil(hasDescendant(matcher)))
}
fun waitElement(element: Matcher<View>, matching: Matcher<View> = isDisplayed()) {
waitForElement(Matchers.allOf(element, matching))
}
我可以这样使用它:
fun waitForButton() {
waitElement(withId(R.id.buttonId))
}
我想要实现的是使用空闲资源与
Kakao KBaseView<*>
喜欢:
private val buttonElement = KButton {withId(R.id.buttonId)}
fun waitForButton() {
buttonElement.waitElement()
}
我刚刚开始在 Android 上进行自动化测试,因此我将不胜感激任何有关如何执行此操作的示例或技巧
由于Kakao没有内置的等待机制,我们可以使用空闲资源逻辑来扩展KBaseView。方法如下:
open class KBaseViewWithIdlingResource<T>(private val viewMatcher: Matcher<View>) : KBaseView<T>() {
private var callback: IdlingResource.ResourceCallback? = null
private fun registerIdlingResource() {
val idlingResource = ViewPropertyChangeCallback(viewMatcher, view)
IdlingRegistry.getInstance().register(idlingResource)
idlingResource.registerIdleTransitionCallback {
callback?.onTransitionToIdle()
IdlingRegistry.getInstance().unregister(idlingResource)
}
}
fun waitUntilDisplayed() {
registerIdlingResource()
Espresso.onView(withId(id)).perform(waitForView())
}
}