关于 flutter-add-integration-test
面向 Flutter 开发者的集成测试指南,介绍项目配置、测试编写与执行,并说明如何借助 Dart/Flutter MCP server 探索应用界面和交互。
主要功能
- 01配置集成测试依赖与入口
- 02通过 MCP 检查组件树
- 03模拟点击、输入和滚动
- 04编写端到端测试
- 05运行测试并分析性能
适用场景
- 01探索应用交互路径后编写测试
- 02验证跨组件的用户流程
- 03在 Chrome 或 Android 上运行测试
- 04排查未挂载组件及动画超时
MCP 相关
指南建议使用 Dart/Flutter MCP server 启动应用、查看组件树,并通过点击、输入和滚动探索交互。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ flutter/ agent-plugins --skill flutter-add-integration-test安装后在 Claude Code 中输入/flutter-add-integration-test确认已加载。
详细介绍
编写 Flutter 集成测试
目录
项目设置与依赖项
配置项目以支持集成测试和 Flutter Driver 扩展。
- 在
pubspec.yaml中添加所需的开发依赖项:flutter pub add 'dev:integration_test:{"sdk":"flutter"}' flutter pub add 'dev:flutter_test:{"sdk":"flutter"}' - 在应用入口点(通常是
lib/main.dart或专用的lib/main_test.dart)中启用 Flutter Driver 扩展:- 导入
package:flutter_driver/driver_extension.dart。 - 在调用
runApp()之前调用enableFlutterDriverExtension();。
- 导入
- 在应用代码的关键组件中添加
Key参数(例如ValueKey('login_button')),确保测试能够可靠地定位它们。
通过 MCP 进行交互式探索
使用 Dart/Flutter MCP 服务工具,在编写静态测试之前交互式地探索和操作应用状态。
- 启动:执行
launch_app,并设置target: "lib/main_test.dart",以启动应用并获取 DTD URI。 - 检查:执行
get_widget_tree,以查找可用的Key、Text节点和组件Type。 - 交互:执行
tap、enter_text和scroll,以模拟用户流程。 - 等待:导航或触发动画时,务必执行
waitFor,或使用get_health验证状态。 - 排查未挂载的组件:如果在组件树中找不到某个组件,它可能是在
SliverList或ListView中延迟加载的。执行scroll或scrollIntoView,使组件挂载后再与其交互。
测试编写指南
使用 flutter_test API 范式组织集成测试。
- 在项目根目录下创建专用的
integration_test/目录。 - 所有测试文件都使用
<name>_test.dart命名约定。 - 在
main()开始处调用IntegrationTestWidgetsFlutterBinding.ensureInitialized();初始化绑定。 - 使用
await tester.pumpWidget(MyApp());加载应用 UI。 - 在
tester.tap()等交互后,使用await tester.pumpAndSettle();触发帧并等待动画完成。 - 使用
expect(find.byKey(ValueKey('foo')), findsOneWidget);或findsNothing断言组件是否可见。 - 使用
await tester.scrollUntilVisible(itemFinder, 500.0, scrollable: listFinder);滚动到特定的屏幕外组件。
旧版 flutter_driver 的条件逻辑:
- 如果要维护或迁移旧版
flutter_driver测试,请使用driver.waitFor()、driver.waitForAbsent()、driver.tap()和driver.scroll(),而不是WidgetTesterAPI。
执行与性能分析
使用 flutter drive 命令执行测试。需要在 test_driver/integration_test.dart 中放置主机驱动脚本,并在其中调用 integrationDriver()。
有条件的执行目标:
- **如果在 Chrome 上测试:**在单独的终端中启动
chromedriver --port=4444,然后运行:flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart -d chrome - **如果测试无头 Web:**使用
-d web-server运行。 - **如果在 Android(本地)上测试:**运行
flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart。 - 如果在 Firebase Test Lab(Android)上测试:
- 构建调试 APK:
flutter build apk --debug - 构建测试 APK:
./gradlew app:assembleAndroidTest - 将两个 APK 上传到 Firebase Test Lab 控制台。
- 构建调试 APK:
工作流:端到端集成测试
复制并遵循此清单,以实现并验证集成测试。
- 任务进度:设置
- 将
integration_test和flutter_test添加到pubspec.yaml。 - 在应用入口点注入
enableFlutterDriverExtension()。 - 为目标控件分配
ValueKey。
- 将
- 任务进度:探索
- 通过 MCP 运行
launch_app。 - 使用
get_widget_tree映射控件树。 - 使用 MCP 工具(
tap、enter_text)验证交互路径。
- 通过 MCP 运行
- 任务进度:编写
- 创建
integration_test/app_test.dart。 - 使用
WidgetTesterAPI 编写测试用例。 - 创建包含
integrationDriver()的test_driver/integration_test.dart。
- 创建
- 任务进度:执行与反馈循环
- 运行
flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart。 - 反馈循环:检查测试输出 -> 如果出现
PumpAndSettleTimedOutException,检查是否存在无限动画 -> 如果未找到控件,添加scrollUntilVisible-> 重新运行测试,直至通过。
- 运行
示例
标准集成测试(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);
});
});
}
主机驱动脚本(test_driver/integration_test.dart)
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();
性能分析驱动脚本(test_driver/perf_driver.dart)
如果使用 binding.traceAction() 包装测试操作以收集性能指标,请使用此驱动脚本。
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,
);
}
},
);
}
评论
支持 Markdown