Flutter集成测试运行器

Testwire是一个基于步骤的Flutter集成测试运行器,通过MCP协议由AI代理控制,支持实时运行、观察、调试和修改测试步骤。

  • by s-philippov
  • Dart
  • 本地部署
  • 11 星标
  • 更新于
在 GitHub 查看 s-philippov/testwire_mcp

使用说明

Flutter的基于步骤的集成测试运行器,由AI代理控制 通过MCP(模型上下文协议)。

Testwire允许AI代理 运行、观察、调试和修改 飘动 实时集成测试——逐一执行操作, 检查结果,通过热重新加载修复故障,并在没有重新加载的情况下重试步骤 重新开始测试。

为什么?

没有Testwire,AI代理的Flutter集成测试工作流程看起来 像这样:写测试→ flutter test → 等待构建和部署→ read 一堵原木墙→ fix → 从头开始重新启动一切每个循环都会燃烧 在重建过程中浪费了几分钟时间,在重新读取相同的详细输出时浪费了令牌。

Testwire改变了这一点:

  • 没有重新启动。 修复一个失败的步骤,热重新加载,重试——不重建 或者重新部署应用程序。
  • 结构化反馈。 代理程序不解析200行日志,而是获取 每一步的干净状态:通过了什么,失败了什么,为什么。
  • 更少的代币。 每个交互返回几行,而不是整个测试 输出。每个重试周期都没有重复的上下文。
  • 在没有代理人的情况下工作。 与正常集成测试相同的测试运行 在CI中 AGENT_MODE 未设置。

包裹

包 版本 描述
testwire 核心库(纯Dart)。提供 step(), TestSession,VM服务扩展。
testwire_flutter 飘动包装纸。提供 TestwireTest (基于类,热重载安全)和 testwireTest() (基于功能,更简单)。
testwire_protocol 共享协议定义——扩展名、响应格式。
testwire_mcp MCP服务器,将AI代理连接到正在运行的测试过程。
example -- 带有演示集成测试的Flutter应用程序示例。

我需要哪些包裹?

用于写作测试 (大多数用户):

  • 添加 testwire_flutter 到您的应用程序 dev_dependencies --它再出口 你需要的一切(testwire 和 testwire_protocol 被拉进来 自动)。

用于运行MCP服务器 (将您的AI代理连接到测试):

  • dart pub global activate testwire_mcp

就是这样——两个包: testwire_flutter 在您的项目中+ testwire_mcp 全球地。

运作原理

  1. flutter run 在设备或模拟器上启动集成测试 随着 --dart-define=AGENT_MODE=true.
  2. 测试注册VM服务扩展并等待代理。
  3. 这 MCP服务器 (testwire_mcp)连接到VM服务并公开 工具: step_forward, run_remaining, retry_step, get_test_state, hot_reload_testwire_test, hot_restart_testwire_test, screenshot, disconnect.
  4. 这 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_mcp

2.配置您的MCP客户端

以下示例使用全局命令 testwire_mcp。如果您已安装 将其替换为开发依赖项 dart run testwire_mcp.

光标

或手动添加到 .cursor/mcp.json:

{
  "mcpServers": {
    "testwire": {
      "command": "testwire_mcp"
    }
  }
}

克劳德代码

claude mcp add --transport stdio testwire -- testwire_mcp

Gemini 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<void> 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 <device_id> \
  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代理)。 看 提案.