1

我在颤振驱动程序测试中体验到片状。

以下代码:

    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。

4

1 回答 1

0

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

希望这可以帮助。

于 2020-03-20T06:04:12.237 回答