$npx -y skills add flutter/agent-plugins --skill flutter-add-integration-testConfigures Flutter Driver for app interaction and converts MCP actions into permanent integration tests. Use when adding integration testing to a project, exploring UI components via MCP, or automating user flows with the integration_test package.
| 1 | # Implementing Flutter Integration Tests |
| 2 | |
| 3 | ## Contents |
| 4 | - [Project Setup and Dependencies](#project-setup-and-dependencies) |
| 5 | - [Interactive Exploration via MCP](#interactive-exploration-via-mcp) |
| 6 | - [Test Authoring Guidelines](#test-authoring-guidelines) |
| 7 | - [Execution and Profiling](#execution-and-profiling) |
| 8 | - [Workflow: End-to-End Integration Testing](#workflow-end-to-end-integration-testing) |
| 9 | - [Examples](#examples) |
| 10 | |
| 11 | ## Project Setup and Dependencies |
| 12 | |
| 13 | Configure the project to support integration testing and Flutter Driver extensions. |
| 14 | |
| 15 | 1. Add required development dependencies to `pubspec.yaml`: |
| 16 | ```bash |
| 17 | flutter pub add 'dev:integration_test:{"sdk":"flutter"}' |
| 18 | flutter pub add 'dev:flutter_test:{"sdk":"flutter"}' |
| 19 | ``` |
| 20 | 2. Enable the Flutter Driver extension in your application entry point (typically `lib/main.dart` or a dedicated `lib/main_test.dart`): |
| 21 | - Import `package:flutter_driver/driver_extension.dart`. |
| 22 | - Call `enableFlutterDriverExtension();` before `runApp()`. |
| 23 | 3. Add `Key` parameters (e.g., `ValueKey('login_button')`) to critical widgets in the application code to ensure reliable targeting during tests. |
| 24 | |
| 25 | ## Interactive Exploration via MCP |
| 26 | |
| 27 | Use the Dart/Flutter MCP server tools to interactively explore and manipulate the application state before writing static tests. |
| 28 | |
| 29 | - **Launch**: Execute `launch_app` with `target: "lib/main_test.dart"` to start the application and acquire the DTD URI. |
| 30 | - **Inspect**: Execute `get_widget_tree` to discover available `Key`s, `Text` nodes, and widget `Type`s. |
| 31 | - **Interact**: Execute `tap`, `enter_text`, and `scroll` to simulate user flows. |
| 32 | - **Wait**: Always execute `waitFor` or verify state with `get_health` when navigating or triggering animations. |
| 33 | - **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. |
| 34 | |
| 35 | ## Test Authoring Guidelines |
| 36 | |
| 37 | Structure integration tests using the `flutter_test` API paradigm. |
| 38 | |
| 39 | - Create a dedicated `integration_test/` directory at the project root. |
| 40 | - Name all test files using the `<name>_test.dart` convention. |
| 41 | - Initialize the binding by calling `IntegrationTestWidgetsFlutterBinding.ensureInitialized();` at the start of `main()`. |
| 42 | - Load the application UI using `await tester.pumpWidget(MyApp());`. |
| 43 | - Trigger frames and wait for animations to complete using `await tester.pumpAndSettle();` after interactions like `tester.tap()`. |
| 44 | - Assert widget visibility using `expect(find.byKey(ValueKey('foo')), findsOneWidget);` or `findsNothing`. |
| 45 | - Scroll to specific off-screen widgets using `await tester.scrollUntilVisible(itemFinder, 500.0, scrollable: listFinder);`. |
| 46 | |
| 47 | **Conditional Logic for Legacy `flutter_driver`:** |
| 48 | - If maintaining or migrating legacy `flutter_driver` tests, use `driver.waitFor()`, `driver.waitForAbsent()`, `driver.tap()`, and `driver.scroll()` instead of the `WidgetTester` APIs. |
| 49 | |
| 50 | ## Execution and Profiling |
| 51 | |
| 52 | Execute tests using the `flutter drive` command. Require a host driver script located in `test_driver/integration_test.dart` that calls `integrationDriver()`. |
| 53 | |
| 54 | **Conditional Execution Targets:** |
| 55 | - **If testing on Chrome:** Launch `chromedriver --port=4444` in a separate terminal, then run: |
| 56 | `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d chrome` |
| 57 | - **If testing headless web:** Run with `-d web-server`. |
| 58 | - **If testing on Android (Local):** Run `flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart`. |
| 59 | - **If testing on Firebase Test Lab (Android):** |
| 60 | 1. Build debug APK: `flutter build apk --debug` |
| 61 | 2. Build test APK: `./gradlew app:assembleAndroidTest` |
| 62 | 3. Upload both APKs to the Firebase Test Lab console. |
| 63 | |
| 64 | ## Workflow: End-to-End Integration Testing |
| 65 | |
| 66 | Copy and follow this checklist to implement and verify integration tests. |
| 67 | |
| 68 | - [ ] **Task Progress: Setup** |
| 69 | - [ ] Add `integration_test` and `flutter_test` to `pubspec.yaml`. |
| 70 | - [ ] Inject `enableFlutterDriverExtension()` into the app entry point. |
| 71 | - [ ] Assign `ValueKey`s to target widgets. |
| 72 | - [ ] **Task Progress: Exploration** |
| 73 | - [ ] Run `launch_app` via MCP. |
| 74 | - [ ] Map the widget tree using `get_widget_tree`. |
| 75 | - [ ] Validate interaction paths using MCP tools (`tap`, `enter_text`). |
| 76 | - [ ] **Task Progress: Authoring** |
| 77 | - [ ] Create `integration_test/app_test.dart`. |
| 78 | - [ ] Write test cases using `WidgetTester` APIs. |
| 79 | - [ ] Create `test_driver/integration_test.dart` with `integrationDriver()`. |
| 80 | - [ ] **Task Progress: Execu |