flutter-testing by flutter/skills
npx skills add https://github.com/flutter/skills --skill flutter-testing为 Flutter 应用程序生成、配置和调试自动化测试,涵盖单元测试、部件测试、集成测试和插件测试。分析架构组件(如 MVVM 层),以生成隔离的、基于模拟的测试和端到端的设备测试。假设为标准 Flutter 项目结构,存在业务逻辑,并熟悉 Dart 测试范式。
评估用户的目标代码,使用以下决策树确定合适的测试策略:
停止并询问用户: "我们今天要测试哪个具体的类、部件或流程?如果尚未提供,请提供相关的源代码。"
单元测试在不渲染 UI 的情况下验证逻辑。它们必须位于 test/ 目录下,并以 _test.dart 结尾。
对于 ViewModels(UI 层逻辑): 模拟 Repository 依赖。不要依赖 Flutter UI 库。
import 'package:test/test.dart'; // 在此处导入你的 ViewModel 和模拟类
void main() { group('HomeViewModel 测试', () { test('成功加载预订', () { final viewModel = HomeViewModel( bookingRepository: FakeBookingRepository()..createBooking(kBooking), userRepository: FakeUserRepository(), );
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
expect(viewModel.bookings.isNotEmpty, true);
});
}); }
对于 Repositories(数据层逻辑): 模拟 API 客户端或本地数据库服务。
import 'package:test/test.dart'; // 在此处导入你的 Repository 和模拟类
void main() { group('BookingRepositoryRemote 测试', () { late BookingRepository bookingRepository; late FakeApiClient fakeApiClient;
setUp(() {
fakeApiClient = FakeApiClient();
bookingRepository = BookingRepositoryRemote(apiClient: fakeApiClient);
});
test('应该获取预订', () async {
final result = await bookingRepository.getBooking(0);
final booking = result.asOk.value;
expect(booking, kBooking);
});
}); }
部件测试验证 UI 渲染和交互。它们必须位于 test/ 目录下,并使用 flutter_test 包。
使用 WidgetTester 来构建部件。
使用 Finder 来定位元素(find.text()、find.byKey()、find.byWidget())。
使用 Matcher 来验证存在性(findsOneWidget、findsNothing、findsNWidgets)。
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { testWidgets('HomeScreen 显示标题并处理点击', (WidgetTester tester) async { // 1. 设置模拟类和 ViewModel final bookingRepository = FakeBookingRepository()..createBooking(kBooking); final viewModel = HomeViewModel( bookingRepository: bookingRepository, userRepository: FakeUserRepository(), );
// 2. 构建部件树
await tester.pumpWidget(
MaterialApp(
home: HomeScreen(viewModel: viewModel),
),
);
// 3. 查找器
final titleFinder = find.text('Home');
final buttonFinder = find.byKey(const Key('increment_button'));
// 4. 断言
expect(titleFinder, findsOneWidget);
// 5. 交互
await tester.tap(buttonFinder);
await tester.pumpAndSettle(); // 等待动画/状态更新完成
expect(find.text('1'), findsOneWidget);
}); }
集成测试在真实设备或模拟器上运行。它们必须位于 integration_test/ 目录下。
确保 pubspec.yaml 的 dev_dependencies 中包含 integration_test。
初始化 IntegrationTestWidgetsFlutterBinding。
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' as app;
void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('端到端应用测试', () { testWidgets('完整流程:点击 FAB 并验证计数器', (WidgetTester tester) async { // 加载完整应用 app.main(); await tester.pumpAndSettle();
// 验证初始状态
expect(find.text('0'), findsOneWidget);
// 查找并点击 FAB
final fab = find.byKey(const ValueKey('increment'));
await tester.tap(fab);
// 触发一帧
await tester.pumpAndSettle();
// 验证状态变化
expect(find.text('1'), findsOneWidget);
});
}); }
如果测试插件,测试必须覆盖 Dart 和原生通信。
android/src/test/ (JUnit)example/ios/RunnerTests/ (XCTest)linux/test/ (GoogleTest)向用户提供运行生成测试的确切命令:
flutter test test/your_test_file.dartflutter test integration_test/your_test_file.dart停止并询问用户: "请使用上面的命令运行测试并粘贴输出。如果测试失败,请提供堆栈跟踪,以便我分析失败原因并生成修复方案。"
_test.dart 结尾。tester.pump() 来推进单帧。仅在等待动画或异步 UI 更新完成时,严格使用 tester.pumpAndSettle()。dart:mirrors: Flutter 不支持反射。依赖代码生成(例如 build_runner、mockito、mocktail)来进行模拟。每周安装量
1.0K
代码仓库
GitHub 星标数
808
首次出现
2026年3月4日
安全审计
安装于
codex981
github-copilot977
opencode977
cursor977
gemini-cli976
kimi-cli975
Generates, configures, and debugs automated tests for Flutter applications, encompassing unit, widget, integration, and plugin testing. Analyzes architectural components (such as MVVM layers) to produce isolated, mock-driven tests and end-to-end device tests. Assumes a standard Flutter project structure, existing business logic, and familiarity with Dart testing paradigms.
Evaluate the user's target code to determine the appropriate testing strategy using the following decision tree:
STOP AND ASK THE USER: "Which specific class, widget, or flow are we testing today? Please provide the relevant source code if you haven't already."
Unit tests verify logic without rendering UI. They must reside in the test/ directory and end with _test.dart.
For ViewModels (UI Layer Logic): Fake the repository dependencies. Do not rely on Flutter UI libraries.
import 'package:test/test.dart'; // Import your ViewModel and Fakes here
void main() { group('HomeViewModel tests', () { test('Load bookings successfully', () { final viewModel = HomeViewModel( bookingRepository: FakeBookingRepository()..createBooking(kBooking), userRepository: FakeUserRepository(), );
expect(viewModel.bookings.isNotEmpty, true);
});
}); }
For Repositories (Data Layer Logic): Fake the API clients or local database services.
import 'package:test/test.dart'; // Import your Repository and Fakes here
void main() { group('BookingRepositoryRemote tests', () { late BookingRepository bookingRepository; late FakeApiClient fakeApiClient;
setUp(() {
fakeApiClient = FakeApiClient();
bookingRepository = BookingRepositoryRemote(apiClient: fakeApiClient);
});
test('should get booking', () async {
final result = await bookingRepository.getBooking(0);
final booking = result.asOk.value;
expect(booking, kBooking);
});
}); }
Widget tests verify UI rendering and interaction. They must reside in the test/ directory and use the flutter_test package.
Use WidgetTester to build the widget.
Use Finder to locate elements (find.text(), find.byKey(), find.byWidget()).
Use Matcher to verify existence (findsOneWidget, findsNothing, findsNWidgets).
import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { testWidgets('HomeScreen displays title and handles tap', (WidgetTester tester) async { // 1. Setup Fakes and ViewModel final bookingRepository = FakeBookingRepository()..createBooking(kBooking); final viewModel = HomeViewModel( bookingRepository: bookingRepository, userRepository: FakeUserRepository(), );
Integration tests run on real devices or emulators. They must reside in the integration_test/ directory.
Ensure integration_test is in dev_dependencies in pubspec.yaml.
Initialize IntegrationTestWidgetsFlutterBinding.
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' as app;
void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('End-to-End App Test', () { testWidgets('Full flow: tap FAB and verify counter', (WidgetTester tester) async { // Load the full app app.main(); await tester.pumpAndSettle();
// Verify initial state
expect(find.text('0'), findsOneWidget);
// Find and tap the FAB
final fab = find.byKey(const ValueKey('increment'));
await tester.tap(fab);
// Trigger a frame
await tester.pumpAndSettle();
// Verify state change
expect(find.text('1'), findsOneWidget);
});
}); }
If testing a plugin, tests must cover both Dart and Native communication.
android/src/test/ (JUnit)example/ios/RunnerTests/ (XCTest)linux/test/ (GoogleTest)Provide the user with the exact command to run the generated test:
flutter test test/your_test_file.dartflutter test integration_test/your_test_file.dartSTOP AND ASK THE USER: "Please run the test using the command above and paste the output. If the test fails, provide the stack trace so I can analyze the failure and generate a fix."
_test.dart.tester.pump() for single frame advances. Use tester.pumpAndSettle() strictly when waiting for animations or asynchronous UI updates to complete.dart:mirrors: Flutter does not support reflection. Rely on code generation (e.g., build_runner, mockito, mocktail) for mocking.Weekly Installs
1.0K
Repository
GitHub Stars
808
First Seen
Mar 4, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex981
github-copilot977
opencode977
cursor977
gemini-cli976
kimi-cli975
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
103,800 周安装
YouTube视频分析师 - 逆向分析病毒内容公式,提取钩子、留存机制与情感触发点
647 周安装
SQLiteData 使用指南:SwiftData 轻量级替代方案,支持 CloudKit 同步
CTF密码学挑战速查指南 | 经典/现代密码攻击、RSA/ECC/流密码实战技巧
648 周安装
Bitrefill CLI:让AI智能体自主购买数字商品,支持加密货币支付
Bilibili 字幕提取工具 - 支持 AI 字幕检测与 ASR 转录,一键下载视频字幕
648 周安装
assistant-ui thread-list 线程列表:管理多聊天线程的 React AI SDK 组件
649 周安装
// 2. Build the Widget tree
await tester.pumpWidget(
MaterialApp(
home: HomeScreen(viewModel: viewModel),
),
);
// 3. Finders
final titleFinder = find.text('Home');
final buttonFinder = find.byKey(const Key('increment_button'));
// 4. Assertions
expect(titleFinder, findsOneWidget);
// 5. Interactions
await tester.tap(buttonFinder);
await tester.pumpAndSettle(); // Wait for animations/state updates to finish
expect(find.text('1'), findsOneWidget);
}); }