Flutter的基于步骤的集成测试运行器,由AI代理控制 通过MCP(模型上下文协议)。
Testwire允许AI代理 运行、观察、调试和修改 飘动 实时集成测试——逐一执行操作, 检查结果,通过热重新加载修复故障,并在没有重新加载的情况下重试步骤 重新开始测试。
为什么?
没有Testwire,AI代理的Flutter集成测试工作流程看起来 像这样:写测试→ flutter test → 等待构建和部署→ read 一堵原木墙→ fix → 从头开始重新启动一切每个循环都会燃烧 在重建过程中浪费了几分钟时间,在重新读取相同的详细输出时浪费了令牌。
Testwire改变了这一点:
- 没有重新启动。 修复一个失败的步骤,热重新加载,重试——不重建
或者重新部署应用程序。
- 结构化反馈。 代理程序不解析200行日志,而是获取
每一步的干净状态:通过了什么,失败了什么,为什么。
- 更少的代币。 每个交互返回几行,而不是整个测试
输出。每个重试周期都没有重复的上下文。
- 在没有代理人的情况下工作。 与正常集成测试相同的测试运行
在CI中 AGENT_MODE 未设置。
包裹
| 包 | 版本 | 描述 |
|---|---|---|
example | -- | 带有演示集成测试的Flutter应用程序示例。 |
我需要哪些包裹?
用于写作测试 (大多数用户):
- 添加
testwire_flutter到您的应用程序dev_dependencies--它再出口
你需要的一切(testwire 和 testwire_protocol 被拉进来 自动)。
用于运行MCP服务器 (将您的AI代理连接到测试):
dart pub global activate testwire_mcp
就是这样——两个包: testwire_flutter 在您的项目中+ testwire_mcp 全球地。
运作原理
flutter run在设备或模拟器上启动集成测试
随着 --dart-define=AGENT_MODE=true.
- 测试注册VM服务扩展并等待代理。
- 这 MCP服务器 (
testwire_mcp)连接到VM服务并公开
工具: step_forward, run_remaining, retry_step, get_test_state, hot_reload_testwire_test, hot_restart_testwire_test, screenshot, disconnect.
- 这 AI 代理 调用这些工具来逐步控制执行。
关键能力
- 逐步执行 --一次跑一步或一次跑完一步。
- 热重载 --编辑测试代码(修复错误、添加步骤)和热重新加载,无需
重新启动。已完成的步骤将自动跳过。
- 重试 --修复代码后重试失败的步骤。
- 优雅的断开连接 --当代理断开连接时,其余步骤将运行
自动,应用程序进程终止。
快速启动
先决条件
- Flutter SDK(3.10+)
- iOS模拟器、Android模拟器或物理设备
- 任何MCP客户端(Cursor、Windsurf、Claude Desktop等)
1.安装MCP服务器
全球地:
dart pub global activate testwire_mcp或者作为项目开发依赖:
dart pub add dev:testwire_mcp2.配置您的MCP客户端
以下示例使用全局命令testwire_mcp。如果您已安装 将其替换为开发依赖项dart run testwire_mcp.
光标

或手动添加到 .cursor/mcp.json:
{
"mcpServers": {
"testwire": {
"command": "testwire_mcp"
}
}
}克劳德代码
claude mcp add --transport stdio testwire -- testwire_mcpGemini CLI
增添 ~/.gemini/settings.json:
{
"mcpServers": {
"testwire": {
"command": "testwire_mcp"
}
}
}副驾驶
增添 mcp.json:
{
"servers": {
"testwire": {
"command": "testwire_mcp"
}
}
}3.写一个测试
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:testwire_flutter/testwire_flutter.dart';
import 'package:integration_test/integration_test.dart';
import 'package:testwire/testwire.dart';
import 'package:my_app/main.dart' as app;
class MyTest extends TestwireTest {
MyTest()
: super(
'My test',
setUp: (tester) async {
app.main();
await tester.pumpAndSettle();
},
);
@override
Future body(WidgetTester tester) async {
await step(
description: 'Tap the button',
context: 'Tap the main action button.',
action: () async {
await tester.tap(find.byKey(const Key('action_button')));
await tester.pumpAndSettle();
},
);
await step(
description: 'Verify result',
context: 'Check that the result text is displayed.',
action: () async {
expect(find.text('Done!'), findsOneWidget);
},
);
}
}
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
registerTestwireExtensions();
MyTest().run();
}4.启动测试
cd example
flutter run \
--dart-define=AGENT_MODE=true \
-d \
integration_test/app_test.dart控制台将打印VM服务URI。代理使用它进行连接。
5.代理人接管
代理通过以下方式连接 connect MCP工具,然后驱动测试 step_forward, run_remaining, get_test_state等等。
示例演示
这 example 目录包括准备运行 演示场景,通过热重载展示bug修复和增量开发。
无代理模式
当 AGENT_MODE 未设置(或 false),全部 step() 调用执行 立即运行,无需暂停——测试就像正常的集成测试一样运行。 这意味着相同的测试文件适用于代理控制和CI 环境。
路线图
testwire_device--一个独立的Dart包,用于控制
通过以下方式从主机访问设备/仿真器 adb (安卓)和 xcrun simctl (iOS模拟器)。权限(授予/撤销/重置),系统 设置、深度链接等——应用程序中没有本机代码,也没有 改变测试的启动方式。作为库(来自测试)和CLI工作 (来自CI脚本)和MCP工具(来自AI代理)。 看 提案.
