Flutter驱动程序如何等待特定元素具有特定文本

Posted

技术标签:

【中文标题】Flutter驱动程序如何等待特定元素具有特定文本【英文标题】:Flutter driver how to wait for specific element to have specific text 【发布时间】:2020-07-01 06:28:36 【问题描述】:

我在 Flutter 驱动程序测试中遇到问题。

以下代码:

    await driver.tap(find.byValueKey('first-name-field'));
    await driver.enterText('');
    await Future.delayed(Duration(milliseconds: 17), () );
    expect(
      await driver.getText(find.byValueKey('first-name-error')),
      equals('Field can't be empty.'),
    );
    await driver.enterText('$#@');
    await Future.delayed(Duration(milliseconds: 17), () );
    expect(
      await driver.getText(find.byValueKey('first-name-error')),
      equals('Field contains unsupported characters.'),
    );
    await driver.enterText('Chris');
    await Future.delayed(Duration(milliseconds: 17), () );
    await driver.waitForAbsent('first-name-error');

它有大约 90% 的成功率,但是有 10% 的时间我期待“字段包含不受支持的字符。”,但我仍然有“字段不能为空”。

代码的工作原理 - TextEditingController 侦听器正在向 ViewModel 报告更改。 ViewModel 有一个流以字符串或 null 的形式提供错误,View 使用 StreamBuilder 显示或隐藏错误标签。

为了缓解这个问题,我引入了单帧延迟(17 毫秒)——它有点帮助,但仍然不稳定。我可以延长延迟,但这会带来测试速度较慢的成本。我找到了一种可以使这个测试更好的方法:

await driver.waitFor(find.text('Field can't be empty.!'))

但是,我不想只在屏幕上找到任何文本,我想专门检查 first-name-error,因为同一屏幕上还有 last-name-error。

【问题讨论】:

【参考方案1】:

Flutter 驱动测试默认是帧同步的。即,它会等到没有挂起的帧。由于您告诉驱动程序等到 17 毫秒,它可能不一定要等到那个时间才能满足挂起的帧条件,因此,一旦驱动程序完成等待 17 毫秒,它将尝试执行下一条语句,这可能不是对其活跃/可见。因此,您可能会看到片状。为避免这种情况,您可能希望将代码包装在 runUnsynchronized() 方法中,这将有助于在禁用帧同步的情况下继续操作。您可以阅读有关此方法的更多信息here。

希望这会有所帮助。

【讨论】:

runUnsynchronized() 如果我没记错的话,当屏幕上有正在进行的动画时使用。你回答后我更新了我的问题。等待 17 毫秒是一种解决方法,我将我的问题用粗体表示。

以上是关于Flutter驱动程序如何等待特定元素具有特定文本的主要内容,如果未能解决你的问题,请参考以下文章

如何在具有特定宽度和高度的矩形中获取 svg 文本元素?

如何使用硒在网页上查找具有特定文本的所有输入元素

如何使用 jQuery 选择具有特定文本的中间节点:包含选择器?

如果元素具有特定颜色,如何与木偶师或剧作家核对?

如何使用 Flutter 在 Firestore 中删除具有特定值的多个文档

如何在 Selenium 中找到具有特定文本的跨度? (使用 Java)