- Implementing Flutter Integration Tests
- Contents
- Project Setup and Dependencies
- Interactive Exploration via MCP
- Test Authoring Guidelines
- Execution and Profiling
- Workflow: End-to-End Integration Testing
- Examples
- Project Setup and Dependencies
- Configure the project to support integration testing and Flutter Driver extensions.
- Add required development dependencies to
- pubspec.yaml
- :
- flutter pub
- add
- 'dev:integration_test:{"sdk":"flutter"}'
- flutter pub
- add
- 'dev:flutter_test:{"sdk":"flutter"}'
- Enable the Flutter Driver extension in your application entry point (typically
- lib/main.dart
- or a dedicated
- lib/main_test.dart
- ):
- Import
- package:flutter_driver/driver_extension.dart
- .
- Call
- enableFlutterDriverExtension();
- before
- runApp()
- .
- Add
- Key
- parameters (e.g.,
- ValueKey('login_button')
- ) to critical widgets in the application code to ensure reliable targeting during tests.
- Interactive Exploration via MCP
- Use the Dart/Flutter MCP server tools to interactively explore and manipulate the application state before writing static tests.
- Launch
-
- Execute
- launch_app
- with
- target: "lib/main_test.dart"
- to start the application and acquire the DTD URI.
- Inspect
-
- Execute
- get_widget_tree
- to discover available
- Key
- s,
- Text
- nodes, and widget
- Type
- s.
- Interact
-
- Execute
- tap
- ,
- enter_text
- , and
- scroll
- to simulate user flows.
- Wait
-
- Always execute
- waitFor
- or verify state with
- get_health
- when navigating or triggering animations.
- Troubleshoot Unmounted Widgets
-
- If a widget is not found in the tree, it may be lazily loaded in a
- SliverList
- or
- ListView
- . Execute
- scroll
- or
- scrollIntoView
- to force the widget to mount before interacting with it.
- Test Authoring Guidelines
- Structure integration tests using the
- flutter_test
- API paradigm.
- Create a dedicated
- integration_test/
- directory at the project root.
- Name all test files using the
_test.dart - convention.
- Initialize the binding by calling
- IntegrationTestWidgetsFlutterBinding.ensureInitialized();
- at the start of
- main()
- .
- Load the application UI using
- await tester.pumpWidget(MyApp());
- .
- Trigger frames and wait for animations to complete using
- await tester.pumpAndSettle();
- after interactions like
- tester.tap()
- .
- Assert widget visibility using
- expect(find.byKey(ValueKey('foo')), findsOneWidget);
- or
- findsNothing
- .
- Scroll to specific off-screen widgets using
- await tester.scrollUntilVisible(itemFinder, 500.0, scrollable: listFinder);
- .
- Conditional Logic for Legacy
- flutter_driver
- :
- If maintaining or migrating legacy
- flutter_driver
- tests, use
- driver.waitFor()
- ,
- driver.waitForAbsent()
- ,
- driver.tap()
- , and
- driver.scroll()
- instead of the
- WidgetTester
- APIs.
- Execution and Profiling
- Execute tests using the
- flutter drive
- command. Require a host driver script located in
- test_driver/integration_test.dart
- that calls
- integrationDriver()
- .
- Conditional Execution Targets:
- If testing on Chrome:
- Launch
- chromedriver --port=4444
- in a separate terminal, then run:
- flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d chrome
- If testing headless web:
- Run with
- -d web-server
- .
- If testing on Android (Local):
- Run
- flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart
- .
- If testing on Firebase Test Lab (Android):
- Build debug APK:
- flutter build apk --debug
- Build test APK:
- ./gradlew app:assembleAndroidTest
- Upload both APKs to the Firebase Test Lab console.
- Workflow: End-to-End Integration Testing
- Copy and follow this checklist to implement and verify integration tests.
- Task Progress: Setup
- Add
- integration_test
- and
- flutter_test
- to
- pubspec.yaml
- .
- Inject
- enableFlutterDriverExtension()
- into the app entry point.
- Assign
- ValueKey
- s to target widgets.
- Task Progress: Exploration
- Run
- launch_app
- via MCP.
- Map the widget tree using
- get_widget_tree
- .
- Validate interaction paths using MCP tools (
- tap
- ,
- enter_text
- ).
- Task Progress: Authoring
- Create
- integration_test/app_test.dart
- .
- Write test cases using
- WidgetTester
- APIs.
- Create
- test_driver/integration_test.dart
- with
- integrationDriver()
- .
- Task Progress: Execution & Feedback Loop
- Run
- flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart
- .
- Feedback Loop
- Review test output -> If
PumpAndSettleTimedOutException
occurs, check for infinite animations -> If widget not found, add
scrollUntilVisible
-> Re-run test until passing.
Examples
Standard Integration Test (
integration_test/app_test.dart
)
import
'package:flutter/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:integration_test/integration_test.dart'
;
import
'package:my_app/main.dart'
;
void
main
(
)
{
IntegrationTestWidgetsFlutterBinding
.
ensureInitialized
(
)
;
group
(
'End-to-end test'
,
(
)
{
testWidgets
(
'tap on the floating action button, verify counter'
,
(
tester
)
async
{
// Load app widget.
await
tester
.
pumpWidget
(
const
MyApp
(
)
)
;
// Verify the counter starts at 0.
expect
(
find
.
text
(
'0'
)
,
findsOneWidget
)
;
// Find the floating action button to tap on.
final
fab
=
find
.
byKey
(
const
ValueKey
(
'increment'
)
)
;
// Emulate a tap on the floating action button.
await
tester
.
tap
(
fab
)
;
// Trigger a frame and wait for animations.
await
tester
.
pumpAndSettle
(
)
;
// Verify the counter increments by 1.
expect
(
find
.
text
(
'1'
)
,
findsOneWidget
)
;
}
)
;
}
)
;
}
Host Driver Script (
test_driver/integration_test.dart
)
import
'package:integration_test/integration_test_driver.dart'
;
Future
<
void
main ( ) =
integrationDriver ( ) ; Performance Profiling Driver Script ( test_driver/perf_driver.dart ) Use this driver script if you wrap your test actions in binding.traceAction() to capture performance metrics. import 'package:flutter_driver/flutter_driver.dart' as driver ; import 'package:integration_test/integration_test_driver.dart' ; Future < void
main ( ) { return integrationDriver ( responseDataCallback : ( data ) async { if ( data != null ) { final timeline = driver . Timeline . fromJson ( data [ 'scrolling_timeline' ] as Map < String , dynamic
, ) ; final summary = driver . TimelineSummary . summarize ( timeline ) ; await summary . writeTimelineToFile ( 'scrolling_timeline' , pretty : true , includeSummary : true , ) ; } } , ) ; }
flutter-add-integration-test
安装
npx skills add https://github.com/flutter/skills --skill flutter-add-integration-test