我在抖动驱动程序测试中遇到了片状感。
以下代码:
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.!'))
但是,我不想只在屏幕上找到任何文本,我想专门检查名字错误,因为同一屏幕上也有姓氏错误。
Flutter驱动程序测试默认情况下是帧同步的。即,它将等待直到没有待处理的帧。由于您要告诉驱动程序等到17 ms,所以不一定要等到那个时间满足挂起的帧条件,因此,一旦驱动程序完成等待17 ms,它将尝试执行下一条语句活动/对其可见。因此,您可能会看到薄脆感。为避免这种情况,您可能需要将代码包装在runUnsynchronized()
方法中,这将有助于在禁用帧同步的情况下继续执行操作。您可以阅读有关此方法的更多信息here。
希望这会有所帮助。