Flutter小部件测试等待动画

5

我有一个类似于以下的小部件测试:

testWidgets('Widget test', (WidgetTester tester) async {
  provideMockedNetworkImages(() async {
    final widget = MyWidget();

    await WidgetTestFunctions.pumpWidgetTest(
      tester,
      widget,
    );

    // ....

    await tester.tap(find.byType(MyWidget));
    await tester.pump(new Duration(milliseconds: 3000));

    // ....

    expect(widget.value, myValue);
  });
});

以下是该小部件 on-tap 方法的实现:
_onButtonPressed() async {      
  await animationController.forward();
  setState(() {
    // ...
    // Calls method that changes the widget value.
  });           
}

我遇到的问题是,在测试中调用animationController.forward()方法后,setState部分没有执行。我应该如何等待此方法正确完成?在应用程序运行时,代码的这部分被正确地调用。
似乎await tester.pump(new Duration(milliseconds: 3000));不起作用,因为动画的持续时间为1500毫秒,而你可以看到pump持续时间是双倍。

你找到答案了吗? - SilkeNL
@SilkeNL 还没有。 - notarealgreal
你尝试过不加时间限制的pump吗?await tester.tap(find.byType(MyWidget)); await tester.pump(new Duration(milliseconds: 3000)); - SilkeNL
我曾经遇到过类似的问题,在 AnimationController.forward 调用后无法找到小部件。 我通过给要测试的小部件分配一个 ValueKey 并使用该键来验证信息来“修复”此问题。 尽管如此,这不是一个解决方案,而更像是一种 hack。 - hman_codes
你好,@notarealgreal,你还没有找到任何解决方案吗? - Valentin Vignal
2个回答

2

不要使用 await tester.pump(new Duration(milliseconds: 3000)); ,而要尝试使用 await tester.pumpAndSettle();

这种类型的 pump 会等待动画结束,然后才会推出帧。


1

我曾遇到相同的问题,以下是发生的情况。

当你这样做时

await animationController.forward();

你不是在等待一个简单的Future<void>完成,而是一个TickerFuture(扩展了Future<void>)。

由于某些原因,在我的测试中,一些来自animationController.forward()TickerFuture被取消了。

TickerProvider的文档中,它说:

如果Ticker在没有停止的情况下被处理,或者在将canceled设置为true的情况下停止,则此Future永远不会完成。

这个类像普通的Future一样工作,但有一个额外的属性orCancel,它返回一个派生的Future,如果返回TickerFuture的Ticker被停止并且canceled设置为true,或者在没有被停止的情况下被处理,则完成一个错误。

要在此future解析或ticker被取消时运行回调,请使用whenCompleteOrCancel。

现在,whenCompleteOrCancel 的问题在于它返回 void(而不是 Future<void>),因此我们无法等待它。

因此,这是我所做的(受到 whenCompleteOrCancel 实现的启发):

Future<void> thunk(dynamic value) {
  return;
}
final TickerFuture ticker = animationController.forward();
await ticker.onCancel.then(thunk, onError: thunk); // <- This resolves even if the ticker is canceled and the tests are not stuck anymore.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接