如何在jetpack compose测试中等待下一个@Composable函数?

Pit*_*try 15 testing user-interface android-jetpack-compose

假设我有 3 个 @Composable 函数:Start、Loading、Result。

在测试中,我调用Start函数,单击其上的Begin按钮,然后调用Loading函数。

Loading函数显示加载过程,需要一些时间,然后调用Result函数。

Result函数呈现一个带有文本OK 的字段。

如何在测试中等待绘制结果 或几秒钟的函数并检查文本是否渲染正常

composeTestRule
    .onNodeWithText("Begin")
    .performClick()

// Here you have to wait ...

composeTestRule
    .onNodeWithText("OK")
    .assertIsDisplayed() 


Run Code Online (Sandbox Code Playgroud)

Jos*_*eca 16

编辑:有新的 waitUntil 函数:

fun waitUntilAtLeastOneExists(matcher: SemanticsMatcher, timeout: Long = 1000L)

fun waitUntilDoesNotExist(matcher: SemanticsMatcher, timeout: Long = 1000L)

fun waitUntilExactlyOneExists(matcher: SemanticsMatcher,  timeout: Long = 1000L)

fun waitUntilNodeCount(matcher: SemanticsMatcher, count: Int, timeout: Long = 1000L)
Run Code Online (Sandbox Code Playgroud)

您可以waitUntil按照评论中的建议使用该功能:

composeTestRule.waitUntil {
    composeTestRule
        .onAllNodesWithText("OK")
        .fetchSemanticsNodes().size == 1
}
Run Code Online (Sandbox Code Playgroud)

有人请求改进此 API,但与此同时,您可以从此博客文章中获取帮助程序并按如下方式使用它:

composeTestRule.waitUntilExists(hasText("OK"))
Run Code Online (Sandbox Code Playgroud)


Pit*_*try 6

所以选项是:

  1. 可以将最后调用的函数写入全局变量。缺点是您需要在每个函数中注册。
  2. 通过视图模型订阅屏幕状态并跟踪它何时到来。缺点是您需要将视图模型拉入测试并了解代码。优点是测试可以快速执行并且不会像计时器那样卡住。
  3. 我做出了这个选择。我写了一个启动异步计时器的函数,即应用程序正在运行,测试等待,计时器结束后继续检查测试。缺点是你设置了一个有时间余量的计时器来完成操作,并且测试需要很长时间才能空闲。优点是你不必深入研究源代码。

实现了这样的功能。

fun asyncTimer (delay: Long = 1000) {
    AsyncTimer.start (delay)
    composeTestRule.waitUntil (
        condition = {AsyncTimer.expired},
        timeoutMillis = delay + 1000
    )
}

object AsyncTimer {
    var expired = false
    fun start(delay: Long = 1000){
        expired = false
        Timer().schedule(delay) {
            expired = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我为测试创建了一个基类并开始编写一个新的测试,我继承并拥有了测试所需的现成功能。