Testwire: Integrating AI Agents into Flutter Integration Testing with MCP and Hot Reload
AI agents struggle with writing Flutter integration tests due to high token usage, long build times, and lack of visual context. Testwire tackles these issues by providing a tool for step-by-step test execution connected to the VM Service via MCP. This lets agents control the process, take screenshots, and use hot reload for quick fixes.
Testwire Architecture and How It Works
Testwire consists of three key components that interact via the Model Context Protocol (MCP). Tests run in flutter run mode with the --dart-define=AGENT_MODE=true flag, enabling debug mode and Dart VM service extensions. The testwire_mcp MCP server connects to the test via VM service, giving the agent a suite of tools for managing execution. As an MCP client, the AI agent uses these tools to monitor step states, run commands, and analyze errors with access to UI visuals.
Key MCP tools available to the agent:
connect: Connect to the test via VM service URI.step_forward: Run the next step and pause.run_remaining: Execute all remaining steps, stopping on error.retry_step: Retry a failed step.get_test_state: Get status of all test steps.hot_reload_testwire_test: Hot reload while preserving progress.hot_restart_testwire_test: Full test restart.screenshot: Capture current UI screenshot.disconnect: Disconnect from the test.
Implementing Tests in Testwire: Code and Structure
Testwire tests are structured as classes extending TestwireTest to support hot reload. Each test breaks into logical steps with states: pending, completed, running, or failed. Steps are defined using the step method, which includes a description, context, and action. Here's an example test structure for validating a feedback form:
class MyTest extends TestwireTest {
MyTest() : super(
'Submit feedback form',
setUp: (tester) async {
app.main();
await tester.pumpAndSettle();
},
);
@override
Future<void> body(WidgetTester tester) async {
await step(
description: 'Navigate to Leave Review',
context: 'Tap the "Leave Review" tile on the home screen.',
action: () async {
await tester.tap(find.byKey(const Key('leave_review_tile')));
await tester.pumpAndSettle();
},
);
await step(
description: 'Enter name',
context: 'Type "Alex" into the name field.',
action: () async {
await tester.enterText(
find.byKey(const Key('name_field')), 'Alex');
await tester.pumpAndSettle();
},
);
await step(
description: 'Tap 5-star rating',
context: 'Tap the 5th star to set rating to 5.',
action: () async {
await tester.tap(find.byKey(const Key('star_5')));
await tester.pumpAndSettle();
},
);
await step(
description: 'Verify result',
context: 'Check that the success message is displayed.',
action: () async {
expect(find.text('Thank you!'), findsOneWidget);
expect(find.text('5 stars from Alex'), findsOneWidget);
},
);
}
}
Hot Reload as the Core Debugging Mechanism
Testwire's hot reload lets agents fix test code without full rebuilds, preserving execution progress. When a step fails, the test pauses, the agent reviews logs, VM state, and UI screenshots, then triggers hot reload and retries. This cuts development cycles from 15–20 minutes to just a few iterations, slashing token costs and context window usage. Hot reload support requires class-based tests (not functions) to maintain state across reloads.
Integration into Development and CI/CD Workflows
Testwire offers two modes: agent mode for development and standard mode for CI/CD. In development, run tests with flutter run --dart-define=AGENT_MODE=true to enable MCP and hot reload. On CI, use flutter test as a regular integration test without extra flags. This single-test-file approach ensures consistency and simplifies maintenance. Integrating Testwire may need agent skill tweaks and docs, but it makes integration testing a core task, not an afterthought.
Key Takeaways
- Testwire fixes AI agent pain points in test writing: high token costs, slow builds, no visual feedback.
- It uses MCP to hook into VM Service, giving agents step-by-step test control.
- Hot reload enables fixes without rebuilds, speeding up dev cycles.
- Tests are class-based for hot reload and dual-mode CI/CD compatibility.
- Setup is needed, but it embeds testing into every dev workflow.
— Editorial Team
No comments yet.