如何等待Espresso测试中的视图

时间:2014-03-12 16:46:40

标签: android android-espresso

我有一个加载textview,显示" loading" string ...我需要等到这个视图消失了......我没有asynctask,因为这个方法在intentService上运行,并在加载完成后发送广播。

有关如何在esspresso测试中等待视图状态更改的任何想法?我需要一些会改变的字符串,并且需要等待......我认为它的情况相同...

感谢您的帮助,neet上没有更多的例子或常见问题。

3 个答案:

答案 0 :(得分:1)

已经回答here

您可以通过向Espresso注册Web服务的IdlingResource来处理此案例。看看this write-up

最有可能的是,您将要使用CountingIdlingResource(它使用一个简单的计数器来跟踪某些内容何时处于空闲状态)。此样本测试演示了如何完成此操作。

答案 1 :(得分:1)

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

第二,定义一个函数,该函数在调用时创建此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类,该类等待TextView的文本更改为某个值。但是,在这种情况下,您可能需要将Matcher函数返回的getConstraints()any(View::class.java)更改为any(TextView::class.java)

答案 2 :(得分: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 调用中,但这将需要更多的代码行,因此我采用这种方式。