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:
- Create the
group(..)
structure insidemain()
- 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
- Pass in the
- 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() }; }}