How to `setUp` a `WidgetTester` for Multiple Tests in Flutter How to `setUp` a `WidgetTester` for Multiple Tests in Flutter flutter flutter

How to `setUp` a `WidgetTester` for Multiple Tests in Flutter


Below is what looks like the current way to solve for this in Flutter.

To summarize:

  1. Create the group(..) structure inside main()
  2. Create your own private methods from inside that structure, for each group of testing you want. For each of these private methods:
    • Pass in the WidgetTester instance
    • Let them be async
  3. And then you should only have a single call to testWidgets(..)
    • Inside this method, is where you call the private methods you set up to distribute test logic
    • Call each of these with await, so they don't run concurrently

So far I didn't find a way for the output to indicate each "sub-test" it ran, so just using print(...) statements for now.

This is a demo for some QR Code logic:

import 'package:flutter/material.dart';import 'package:flutter_test/flutter_test.dart';import 'package:mockito/mockito.dart';import 'package:qr_code_demo/app/appRoutes.dart';import 'package:qr_code_demo/view/appHome.dart';import 'package:qr_code_demo/view/qrScanner.dart';class MockNavigatorObserver extends Mock implements NavigatorObserver {}void main() {  group('MainPage navigation tests', () {    NavigatorObserver mockObserver;    _loadAppHomeScreen(WidgetTester tester) async {      await tester.pumpWidget(        MaterialApp(          routes: AppRoutes.getRouteMap(),          home: AppHomeScreen(),          navigatorObservers: [mockObserver],        ),      );    }    setUp(() {      mockObserver = MockNavigatorObserver();    });    Future<Null> _verifyLayoutElements(WidgetTester tester) async {      print('_verifyLayoutElements');      expect(find.byIcon(Icons.scanner), findsOneWidget);      expect(find.byType(FloatingActionButton), findsOneWidget);      expect(find.byType(RaisedButton), findsOneWidget);    }    Future<Null> _navigateToQrScannerScreen(WidgetTester tester) async {      print('_navigateToQrScannerScreen');      await tester.tap(find.byIcon(Icons.scanner));      await tester.pumpAndSettle();      verify(mockObserver.didPush(any, any));      expect(find.byType(AppHomeScreen), findsNothing);      expect(find.byType(QrScannerScreen), findsOneWidget);    }    testWidgets('AppHomeScreen WidgetTester', (WidgetTester tester) async {      await _loadAppHomeScreen(tester);      await _verifyLayoutElements(tester);      await _navigateToQrScannerScreen(tester);    });  });}

Thanks to:https://iiro.dev/2018/08/22/writing-widget-tests-for-navigation-events/

  • Scroll to code for this file: test/navigation_test.dart

====

And double-thanks, because the navigation testing logic including with this example is thanks to @iiro's post: https://stackoverflow.com/a/51983194/2162226

Here is the appRoutes.dart file:

import 'package:qr_code_demo/view/appHome.dart';import 'package:qr_code_demo/view/qrScanner.dart';  class AppRoutes {  static const String AppHome = 'AppHome';  static const String QrScanner = 'QrScanner';  static String initialRoute() {    return AppHome;  }    static getRouteMap() {        return {      AppRoutes.AppHome: (context) => AppHomeScreen(),      AppRoutes.QrScanner: (context) => QrScannerScreen()    };      }}