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驱动程序如何等待特定元素具有特定文本的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jQuery 选择具有特定文本的中间节点:包含选择器?