测试与调试组件

测试与调试组件用于确保应用质量和性能。

提示:良好的测试实践可以提高代码质量和维护性。
Widget 测试结果
2
总测试数
2
通过
0
失败
MyWidget 显示正确的文本
12ms
点击按钮后文本改变
8ms

Widget Tests

Widget Tests 用于测试 UI 组件的行为和外观。

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('MyWidget 显示正确的文本', (WidgetTester tester) async {
    // 构建 Widget
    await tester.pumpWidget(MyWidget());

    // 验证文本
    expect(find.text('Hello'), findsOneWidget);
  });

  testWidgets('点击按钮后文本改变', (WidgetTester tester) async {
    await tester.pumpWidget(MyWidget());

    // 查找按钮并点击
    await tester.tap(find.byType(ElevatedButton));
    await tester.pump();

    // 验证文本已改变
    expect(find.text('Clicked'), findsOneWidget);
  });
}
Unit 测试结果
✓ Calculator (4 tests)
加法 - 2 + 3 = 5
减法 - 5 - 3 = 2
乘法 - 3 × 4 = 12
除法 - 10 ÷ 2 = 5
All tests passed in 24ms

Unit Tests

Unit Tests 用于测试单个函数或类的逻辑。

import 'package:flutter_test/flutter_test.dart';

void main() {
  group('Calculator', () {
    test('加法', () {
      expect(add(2, 3), equals(5));
    });

    test('减法', () {
      expect(subtract(5, 3), equals(2));
    });

    test('乘法', () {
      expect(multiply(3, 4), equals(12));
    });

    test('除法', () {
      expect(divide(10, 2), equals(5));
    });
  });
}

Integration Tests

Integration Tests 用于测试完整的应用流程。

import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';

void main() {
  group('Counter App', () {
    late FlutterDriver driver;

    setUpAll(() async {
      driver = await FlutterDriver.connect();
    });

    tearDownAll(() async {
      await driver.close();
    });

    test('计数器递增', () async {
      // 查找按钮
      final counterTextFinder = find.byValueKey('counter');
      final buttonFinder = find.byValueKey('increment');

      // 验证初始值
      expect(await driver.getText(counterTextFinder), "0");

      // 点击按钮
      await driver.tap(buttonFinder);

      // 验证新值
      expect(await driver.getText(counterTextFinder), "1");
    });
  });
}
Golden 测试对比
Golden 文件
goldens/my_widget.png
实际渲染
Widget 渲染结果
✓ 匹配成功
像素差异: 0%
尺寸: 200x100

Golden Tests

Golden Tests 用于验证 Widget 的视觉效果。

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('MyWidget 视觉测试', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: MyWidget(),
      ),
    );

    await expectLater(
      find.byType(MyWidget),
      matchesGoldenFile('goldens/my_widget.png'),
    );
  });
}

Mockito

Mockito 用于创建模拟对象进行测试。

import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

class MockService extends Mock implements Service {}

void main() {
  group('UserService', () {
    late MockService mockService;
    late UserService userService;

    setUp(() {
      mockService = MockService();
      userService = UserService(mockService);
    });

    test('获取用户数据', () async {
      // 设置模拟返回值
      when(mockService.fetchUser('123'))
          .thenAnswer((_) async => User(id: '123', name: 'John'));

      // 执行测试
      final user = await userService.getUser('123');

      // 验证结果
      expect(user.name, equals('John'));
      verify(mockService.fetchUser('123')).called(1);
    });
  });
}
测试最佳实践:
  • 为每个功能编写单元测试
  • 为关键 UI 编写 Widget 测试
  • 为主要流程编写集成测试
  • 使用模拟对象隔离依赖
  • 保持测试代码简洁和可维护
测试金字塔
E2E 测试
少量
Widget 测试
适量
Unit 测试
大量
🟢 Unit 测试: 70% - 快速、独立、覆盖逻辑
🔵 Widget 测试: 20% - 测试 UI 组件
🟠 E2E 测试: 10% - 测试完整流程
运行测试命令:
  • flutter test: 运行所有测试
  • flutter test test/widget_test.dart: 运行特定测试
  • flutter drive --target=test_driver/app.dart: 运行集成测试
  • flutter test --update-goldens: 更新 golden 文件