11

我尝试将旧的颤振驱动程序测试迁移到新的integration_test 包我从示例项目中复制了几乎所有内容,并在本地执行了示例项目的集成测试。这按预期工作,我能够看到应用程序 UI。但是我自己的应用程序在显示初始屏幕后仅以紫色显示“测试开始...”。

example_test.dart:

void main() {
  group('My-App', () {
    final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized() as IntegrationTestWidgetsFlutterBinding;

    testWidgets('Tap on SkipAuthentication', (tester) async {
      app.main();

      await binding.traceAction(() async {
        await tester.pumpAndSettle();

        await Future.delayed(Duration(seconds: 5));

        final fab = find.byKey(ValueKey(WidgetKeys.authenticationScreenKeys.skipAuthenticationButton));
        await tester.tap(fab);

        await tester.pumpAndSettle();
      });
    });



integration_driver.dart:

Future<void> main() async {
  integrationDriver();
}

我发现,如果我不启动 tester.pumpWidget() 会显示 Widget,我会传递给该方法,但那是 WidgetTest 而不是集成测试。

我的猜测是,这是因为我的 main 函数是一个异步函数。在我的旧颤振驱动程序测试中,我还需要这种解决方法来等待第一帧。但我不知道如何使用新的 integration_test 包来实现它。

希望您能够帮助我。

4

4 回答 4

1

我也有这个问题,sleep/Future.delayed没有工作。有时会运行集成测试,但大多数情况下并未运行。

最终为我解决问题的是将framePolicyof更改IntegrationTestWidgetsFlutterBindingLiveTestWidgetsFlutterBindingFramePolicy.fullyLive. 这是一个完整的例子:

void main() {
  final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized()
      as IntegrationTestWidgetsFlutterBinding;

  binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;

  testWidgets("failing test example", (WidgetTester tester) async {
    app.main();
    await tester.pumpAndSettle();

    // Start testing here...
  });
}

该解决方案是从Google Codelabs中找到的。

于 2021-06-23T12:05:25.487 回答
1

我也为此苦苦挣扎了几个小时,终于找到了答案。

你的问题是不要用await tester.pumpWidget(MyApp())

你的测试看起来像:

void main() {
    testWidgets('Tap on SkipAuthentication', (tester) async {
      app.main(); // <--- You call app.main() - This Flutter Driver style, but not integration test style

      await binding.traceAction(() async {
        await tester.pumpAndSettle();

        await Future.delayed(Duration(seconds: 5));

        final fab = find.byKey(ValueKey(WidgetKeys.authenticationScreenKeys.skipAuthenticationButton));
        await tester.tap(fab);

        await tester.pumpAndSettle();
      });
    });

您需要像这样更改测试:

void main() {
  testWidgets('Tap on SkipAuthentication', (tester) async {
    await tester.pumpWidget(MyApp()); // You need to call await tester.pumpWidget();
    await tester.pump(const Duration(seconds: 1));

    final fab = find.byKey(ValueKey(WidgetKeys.authenticationScreenKeys.skipAuthenticationButton));
    await tester.tap(fab);

    await tester.pump();
  });
}
于 2021-06-28T22:01:20.133 回答
1

嗯。我开始flutter_driver在假期转换我的测试并遇到同样的事情。

我的解决方法是在启动测试后添加一个固定的睡眠,这允许它正确初始化。所以一个测试用例看起来像这样:

    testWidgets("Main screen loads", (WidgetTester widgetTester) async {
      app.main();
      await sleep(Duration(seconds: 10));
      await widgetTester.pumpAndSettle();

      expect(find.text("What are you looking for?"), findsOneWidget);
    });
于 2020-12-23T14:23:02.280 回答
0

我不得不使用来自这个线程的命令组合来使我的测试工作。起初,它也卡在“测试开始...”上,然后卡在启动画面上。在这两种情况下,它都无法移动到应用程序的第一页,因此我找不到任何小部件。

我从所有的尝试中学到了一些东西:

  • 显然,pumpAndSettle()与它的论点一起使用会产生与不使用持续时间的plusDuration不同的结果。第一个对我有用以“获取”应用程序的第一页,但不是后者sleep(Duration)pumpAndSettle()
  • 调用tester.pumpWidget(MyApp())而不是app.main()实际上导致我出现错误屏幕,我绝对需要使用app.main()
  • framePolicy我的情况下,设置也是必要的
  • 我认为 using ValueKeyor Keyinsidefind.byKey是一样的:对我来说,他们都在工作(给他们一个字符串作为参数)

最后,对我有用的代码是:

void main() {
  final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized() 
    as IntegrationTestWidgetsFlutterBinding;
  binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
    
  testWidgets('Tap on SkipAuthentication', (tester) async {
    app.main();
    await tester.pumpAndSettle(Duration(seconds: 3));

    final fab = find.byKey(ValueKey(WidgetKeys.authenticationScreenKeys.skipAuthenticationButton));
    await tester.tap(fab);

    await tester.pumpAndSettle();
  });
}
于 2021-07-02T15:15:34.983 回答