Flutter 集成测试 - 状态不佳,无元素

Posted

技术标签:

【中文标题】Flutter 集成测试 - 状态不佳,无元素【英文标题】:Flutter integration test - bad state, no element 【发布时间】:2021-04-11 05:18:58 【问题描述】:

在我的集成测试中,我必须继续这样做:await tester.pumpAndSettle(const Duration(seconds: [some duration])); 在动画延迟后等待小部件加载到屏幕上,否则我会收到错误:“bad state: no element”。

这是处理此问题的最佳方法吗?我发现现在我正在尝试将集成测试添加到我的持续集成平台中,这非常不稳定。我不得不增加更多的时间来等待,这感觉很糟糕(竞争条件),并且由于构建时间需要更长的时间,也会增加持续集成的成本。下面是代码示例:

Future<void> registerUserPasswordButtonShouldBeDisabled() async 
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
  testWidgets('''registering a new user with non-unique email address disables 
  register password button''', (WidgetTester tester) async 
    await app.main();
    await tester.pumpAndSettle(const Duration(seconds: 5));

    final registerButton = find.byKey(const Key('register'));

有没有更好的方法来处理由于动画延迟导致小部件在某些延迟之前不会出现在屏幕上的“错误状态:无元素”错误?

【问题讨论】:

【参考方案1】:

你试过不带duration参数吗?

await tester.pumpAndSettle();

如果您在显示按钮之前有一个动画加载微调器和一些过渡,那么pumpAndSettle 将等待所有这些动画停止并且不会比默认的 100 毫秒长一毫秒,这不会浪费时间。

参考:the docs

【讨论】:

是的,我最初确实尝试过,但是等待的时间不够长。这可能是因为我的动画在开始动画之前有很长的延迟,所以它们根本不存在。 您不想或不能做动画的原因可能有很多,但也许更早开始制作动画?这是一个非常好的问题,我希望看到社区提供更好的答案。【参考方案2】:

我遇到了同样的问题,并为waitFor写了一个小替换:

Future<void> waitFor(Finder finder, [timeoutInSeconds = 10]) 
  Completer c = Completer();
  Timer poll;
  Timer timeout;

  poll = Timer.periodic(Duration(milliseconds: 500), (_) 
    if (finder.evaluate().isNotEmpty) 
      poll.cancel();
      timeout.cancel();
      c.complete();
    
  );

  timeout = Timer(Duration(seconds: timeoutInSeconds), () 
    poll.cancel();
    c.completeError('WaitFor timed out for $finder.description');
  );

  return c.future;

【讨论】:

以上是关于Flutter 集成测试 - 状态不佳,无元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在集成测试中模拟 BLoC

Flutter Firebase:状态不佳:快照既没有数据也没有错误

flutter集成测试

Flutter集成测试

我们如何在 Flutter 中为集成测试生成 json 报告?

在 Flutter 中使用 Flutter Driver 对 OTPTextField 小部件进行集成测试