7

我有一个TextView显示“正在加载”的字符串......我需要等到这个视图消失......我没有句柄,Asynctask因为这个方法在 a 中运行IntentService并在加载时发送广播完成的。

关于如何在 Espresso 测试中等待视图状态更改的任何想法?我需要一些相同的字符串,这些字符串会改变并且需要等待......我想这是同样的情况......

谢谢您的帮助。网络上没有太多示例或常见问题解答。

4

3 回答 3

3

您可以定义一个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)

于 2020-08-17T16:03:53.000 回答
2

这已经回答here

您可以通过使用 Espresso 为您的 Web 服务注册 IdlingResource 来处理这种情况。看看这篇文章

最有可能的是,您会想要使用 CountingIdlingResource(它使用一个简单的计数器来跟踪某事何时空闲)。此示例测试演示了如何做到这一点。

于 2014-03-17T15:43:42.943 回答
0

这是我处理这种情况的方法:

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调用中的代码,但这将是更多的代码行,因此我采用这种方式。

于 2021-07-26T11:08:01.100 回答