Flutter 测试详解
Flutter 测试详解
一、测试概述
Flutter 测试包括单元测试、Widget 测试和集成测试。良好的测试可以确保代码质量和功能正确性。
1.1 测试类型
- 单元测试- 测试单个函数、方法或类
- Widget 测试- 测试单个 Widget 的行为
- 集成测试- 测试多个组件或整个应用的交互
二、单元测试
2.1 创建测试文件
// test/counter_test.dart import 'package:test/test.dart'; import 'package:my_app/counter.dart'; void main() { group('Counter', () { late Counter counter; setUp(() { counter = Counter(); }); test('initial value is 0', () { expect(counter.value, 0); }); test('increment increases value by 1', () { counter.increment(); expect(counter.value, 1); }); test('decrement decreases value by 1', () { counter.decrement(); expect(counter.value, -1); }); }); }2.2 运行测试
flutter test test/counter_test.dart三、Widget 测试
3.1 创建测试文件
// test/widget_test.dart import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:my_app/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { await tester.pumpWidget(const MyApp()); expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); await tester.tap(find.byIcon(Icons.add)); await tester.pump(); expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); }3.2 常用匹配器
findsOneWidget // 找到一个 Widget findsNothing // 没找到任何 Widget findsWidgets // 找到多个 Widget isTrue // 为真 isFalse // 为假 equals // 相等 throwsA // 抛出异常四、集成测试
4.1 创建测试文件
// integration_test/app_test.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(); testWidgets('full app test', (WidgetTester tester) async { await tester.pumpWidget(const MyApp()); await tester.pumpAndSettle(); // 测试首页 expect(find.text('Welcome'), findsOneWidget); // 导航到设置页面 await tester.tap(find.byIcon(Icons.settings)); await tester.pumpAndSettle(); expect(find.text('Settings'), findsOneWidget); }); }4.2 运行集成测试
flutter test integration_test/app_test.dart五、Mock 测试
5.1 使用 mockito
dev_dependencies: mockito: ^5.4.05.2 创建 Mock 类
import 'package:mockito/mockito.dart'; class MockApiService extends Mock implements ApiService {} void main() { late MockApiService mockApi; setUp(() { mockApi = MockApiService(); }); test('fetch data from api', () async { when(mockApi.fetchUsers()).thenAnswer((_) async => [User(id: 1, name: 'Test')]); final users = await mockApi.fetchUsers(); expect(users.length, 1); verify(mockApi.fetchUsers()).called(1); }); }六、测试最佳实践
6.1 测试结构
group('Feature', () { setUp(() { // 每个测试前的准备 }); tearDown(() { // 每个测试后的清理 }); test('test case 1', () { // 测试逻辑 }); test('test case 2', () { // 测试逻辑 }); });6.2 测试命名
// 好的命名 test('counter initializes to 0', () {}); test('tapping button increments counter', () {}); // 不好的命名 test('test 1', () {}); test('counter works', () {});七、覆盖率报告
7.1 生成覆盖率
flutter test --coverage7.2 查看报告
genhtml coverage/lcov.info -o coverage/html open coverage/html/index.html八、总结
测试是保证代码质量的关键:
- 单元测试- 测试单个功能单元
- Widget 测试- 测试 UI 组件
- 集成测试- 测试整体流程
- Mock 测试- 隔离外部依赖
- 覆盖率- 确保测试覆盖
合理的测试可以提高代码的可靠性和可维护性。
