New integration_test package just shows "Test starting..." [Android]

Viewed 2011

I tried to migrate my old flutter driver tests to the new integration_test package. I copied nearly everything from the example project and executed the integration tests of the example project locally. That worked as expected, I was able to see the app UI. But my own app just shows "Test starting..." in a purple color after the splash screen was shown.

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();
}

I figured out, that if I don't start the tester.pumpWidget() shows the Widget, that I pass to the method, but thats a WidgetTest and not an integration Test.

My guess is, that it's due to the fact that my main function is an async function. I also needed this workaround in my old flutter driver tests to wait for the first frame. But I couldn't figure out how to implement that with the new integration_test package.

Hope you can help me.

4 Answers

I had this issue also and the sleep / Future.delayed did not work. Some times the integration tests were run but mostly they were not.

What ultimately fixed the issue for me was to change the framePolicy of IntegrationTestWidgetsFlutterBinding to LiveTestWidgetsFlutterBindingFramePolicy.fullyLive. Here is a full example:

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...
  });
}

The solution was found from Google Codelabs.

Huh. I started converting my flutter_driver tests over the holidays and ran into the same thing.

My fix was to add a fixed sleep after launching the test, which allowed it to initialize properly. So one test case looks like this:

    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);
    });

I was struggling with this also for some hours and finally found the answer.

Your issue is that do not pump a widget with await tester.pumpWidget(MyApp())

Your test look like:

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();
      });
    });

You need to change your test like this:

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();
  });
}

I had to use a combination of commands from this thread to make my test work. At first, it was getting stuck on "Test starting..." for me as well, then it was getting stuck on the splash screen. In both cases, it could not move to the first page of the app, so I could not find any widget.

A few things I kind-of learned from all my tries:

  • apparently, using pumpAndSettle() with its Duration argument gives different results than sleep(Duration) plus pumpAndSettle() without duration. The first worked for me to "get" the app's first page, but not the latter
  • calling tester.pumpWidget(MyApp()) instead of app.main() is actually resulting in an error screen for me, I definitely need to use app.main()
  • the framePolicy setting is necessary in my case as well
  • I think that using ValueKey or Key inside find.byKey is the same: for me, both of them are working (giving them a string as argument)

In the end, the code that works for me is:

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();
  });
}
Related