我有一个TextView
显示“正在加载”的字符串......我需要等到这个视图消失......我没有句柄,Asynctask
因为这个方法在 a 中运行IntentService
并在加载时发送广播完成的。
关于如何在 Espresso 测试中等待视图状态更改的任何想法?我需要一些相同的字符串,这些字符串会改变并且需要等待......我想这是同样的情况......
谢谢您的帮助。网络上没有太多示例或常见问题解答。
我有一个TextView
显示“正在加载”的字符串......我需要等到这个视图消失......我没有句柄,Asynctask
因为这个方法在 a 中运行IntentService
并在加载时发送广播完成的。
关于如何在 Espresso 测试中等待视图状态更改的任何想法?我需要一些相同的字符串,这些字符串会改变并且需要等待......我想这是同样的情况......
谢谢您的帮助。网络上没有太多示例或常见问题解答。
您可以定义一个ViewAction
持续循环主线程的循环,直到有View
问题的可见性更改为View.GONE
或经过最大时间量。
首先,定义ViewAction
如下:
/**
* A [ViewAction] that waits up to [timeout] milliseconds for a [View]'s visibility value to change to [View.GONE].
*/
class WaitUntilGoneAction(private val timeout: Long) : ViewAction {
override fun getConstraints(): Matcher<View> {
return any(View::class.java)
}
override fun getDescription(): String {
return "wait up to $timeout milliseconds for the view to be gone"
}
override fun perform(uiController: UiController, view: View) {
val endTime = System.currentTimeMillis() + timeout
do {
if (view.visibility == View.GONE) return
uiController.loopMainThreadForAtLeast(50)
} while (System.currentTimeMillis() < endTime)
throw PerformException.Builder()
.withActionDescription(description)
.withCause(TimeoutException("Waited $timeout milliseconds"))
.withViewDescription(HumanReadables.describe(view))
.build()
}
}
其次,定义一个函数,在调用时创建一个 this 的实例ViewAction
,如下:
/**
* @return a [WaitUntilGoneAction] instance created with the given [timeout] parameter.
*/
fun waitUntilGone(timeout: Long): ViewAction {
return WaitUntilGoneAction(timeout)
}
第三也是最后,ViewAction
在您的测试方法中调用它,如下所示:
onView(withId(R.id.loadingTextView)).perform(waitUntilGone(3000L))
您可以采用此概念并类似地创建一个WaitForTextAction
等待 aTextView
的文本更改为某个值的类。但是,在这种情况下,您可能希望将函数Matcher
返回的getConstraints()
值从更改any(View::class.java)
为any(TextView::class.java)
。
这是我处理这种情况的方法:
public void waitForViewToDisappear(int viewId, long maxWaitingTimeMs) {
long endTime = System.currentTimeMillis() + maxWaitingTimeMs;
while (System.currentTimeMillis() <= endTime) {
try {
onView(allOf(withId(viewId), isDisplayed())).matches(not(doesNotExist()));
} catch (NoMatchingViewException ex) {
return; // view has disappeared
}
}
throw new RuntimeException("timeout exceeded"); // or whatever exception you want
}
注意:matches(not(doesNotExist()))
是一种“noop”匹配器;它只是为了确保onView
零件实际运行。您同样可以编写一个ViewAction
什么都不做并将其包含在perform
调用中的代码,但这将是更多的代码行,因此我采用这种方式。