[鸿蒙2025领航者闯关] Flutter + OpenHarmony 自动化测试体系:从单元测试到真机巡检的全链路保障

作者:晚霞的不甘
日期:2025年12月5日
标签:Flutter · OpenHarmony · 自动化测试 · 单元测试 · 集成测试 · UI 测试 · CI/CD · 质量保障


引言:没有测试的代码,是技术债的开始

在 OpenHarmony 多设备、多场景、高可靠性的要求下,“能跑”不等于“可用”
一个未被充分测试的 Flutter 应用可能:

  • 在手表上因内存溢出崩溃
  • 在车机横屏时布局错乱
  • 在分布式调用中泄露用户数据
  • 在升级后丢失本地缓存

自动化测试不是成本,而是对稳定性的投资

本文构建一套分层、可扩展、可集成的测试体系,覆盖 Dart 逻辑、UI 交互、OpenHarmony 原生能力、多设备兼容性 四大维度,助你实现 90%+ 测试覆盖率、每日自动回归、上线零重大缺陷 的质量目标。


一、测试金字塔:分层策略与投入比例

         ┌──────────────────────┐
         │   E2E / UI 测试      │ ← 10%(高成本,低频)
         ├──────────────────────┤
         │   集成测试           │ ← 20%(验证模块协作)
         ├──────────────────────┤
         │   单元测试           │ ← 70%(快速反馈,高覆盖)
         └──────────────────────┘

黄金法则

  • 单元测试:验证逻辑正确性(如 UseCase、工具函数)
  • 集成测试:验证模块间协作(如 Repository + DataSource)
  • UI 测试:验证用户可见行为(如按钮点击、页面跳转)

二、单元测试:Dart 逻辑的基石

2.1 工具链

  • 测试框架test(官方)
  • Mock 框架mocktail(无反射,兼容 Flutter Web & OH)
  • 覆盖率工具flutter test --coverage

2.2 示例:测试 UseCase

// feature_health/domain/use_cases/fetch_health_data_test.dart
void main() {
  late MockHealthRepository mockRepo;
  late FetchHealthDataUseCase useCase;

  setUp(() {
    mockRepo = MockHealthRepository();
    useCase = FetchHealthDataUseCase(mockRepo);
  });

  test('should return health data when repository succeeds', () async {
    // Arrange
    final testData = HealthData(heartRate: 72);
    when(() => mockRepo.getHealthData()).thenAnswer((_) async => testData);

    // Act
    final result = await useCase();

    // Assert
    expect(result, equals(testData));
    verify(() => mockRepo.getHealthData()).called(1);
  });
}

2.3 覆盖率要求

  • 核心业务模块 ≥ 85%
  • 工具类 ≥ 95%
  • UI Widget 不强制(由 Widget Test 覆盖)

运行并生成报告:

flutter test --coverage
genhtml coverage/lcov.info -o coverage/html

三、Widget 测试:验证 UI 结构与交互

3.1 使用 flutter_test

testWidgets('HealthPage shows heart rate', (tester) async {
  // Arrange
  final useCase = MockFetchHealthDataUseCase();
  when(() => useCase()).thenAnswer((_) async => HealthData(heartRate: 80));

  // Act
  await tester.pumpWidget(
    MaterialApp(
      home: HealthPage(fetchData: useCase),
    ),
  );

  // Assert
  expect(find.text('心率: 80'), findsOneWidget);
  expect(find.byIcon(Icons.favorite), findsOneWidget);
});

3.2 关键检查点

  • 文本是否正确渲染
  • 按钮是否可点击
  • 加载状态是否显示
  • 错误提示是否出现
  • 响应式布局是否适配(通过 tester.view.size 模拟不同屏幕)

四、集成测试:端到端业务流验证

4.1 使用 integration_test

// test_driver/app_test.dart
void main() {
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();

  testWidgets('User can navigate to health report', (tester) async {
    await app.main(); // 启动完整应用
    await tester.pumpAndSettle();

    // 点击健康 Tab
    await tester.tap(find.text('健康'));
    await tester.pumpAndSettle();

    // 验证报告页面加载
    expect(find.text('本周健康摘要'), findsOneWidget);
  });
}

4.2 运行方式

# 在 OpenHarmony 设备上运行
flutter drive \
  --driver=test_driver/integration_test.dart \
  --target=integration_test/app_test.dart \
  --platform=openharmony

⚠️ 注意:集成测试需真实或模拟的 OpenHarmony 环境。


五、OpenHarmony 原生能力测试

5.1 插件测试策略

对于自定义插件(如 oh_health_sensor):

  • Dart 层:Mock MethodChannel 响应
  • ArkTS 层:使用 @ohos:hypium 编写原生测试
// oh_health_sensor/test/OhHealthSensorPlugin.test.ets
import { describe, it, expect } from '@ohos:hypium';

describe('OhHealthSensorPlugin', function () {
  it('getModel returns valid string', function () {
    const model = deviceInfo.deviceModel;
    expect(model).isNotEmpty();
  });
});

5.2 权限与异常测试

  • 模拟权限拒绝场景
  • 验证错误回调是否触发
  • 检查资源是否释放(如传感器监听器)

六、多设备兼容性测试(真机巡检)

6.1 使用 DevEco Cloud Lab

华为提供 远程真机集群,支持:

  • 华为 Watch 4 Pro(OH 4.0)
  • Mate 60(OH 4.1)
  • HiCar 车机(OH 4.0)
  • Vision 智慧屏(OH 4.1)

6.2 自动化巡检脚本

# .devcloud/pipeline.yaml
stages:
  - name: Compatibility Test
    steps:
      - script: |
          for device in watch phone car tv; do
            flutter drive \
              --target=integration_test/smoke_test.dart \
              --device-id=$device \
              --platform=openharmony
          done

6.3 检查项

设备 验证重点
手表 内存 ≤ 50MB,启动 ≤ 2s
车机 横屏布局正确,焦点导航可用
智慧屏 字体 ≥ 20sp,遥控器可操作
手机 横竖屏切换无异常

七、CI/CD 集成:质量门禁自动化

7.1 GitLab CI 示例

stages:
  - test
  - build
  - deploy

unit_test:
  stage: test
  script:
    - flutter test --coverage
    - genhtml coverage/lcov.info -o report
  artifacts:
    paths: [report/]

ui_test:
  stage: test
  script:
    - flutter test test/widget/

integration_test_oh:
  stage: test
  script:
    - hdc shell aa start -b com.example.app  # 安装到连接设备
    - flutter drive --target=integration_test/app_test.dart --platform=openharmony

7.2 质量门禁规则

  • 单元测试覆盖率 < 80% → 阻断合并
  • 任一测试失败 → 标记为失败
  • 静态分析警告 → 记录但不阻断

八、测试最佳实践清单

✅ 所有新功能必须附带单元测试
✅ 核心页面必须有 Widget Test
✅ 每次 PR 触发 CI 全量测试
✅ 每日凌晨执行真机兼容性巡检
✅ 测试代码与业务代码同生命周期维护
✅ 禁止提交 // ignore: test 注释


结语:测试,是工程师的承诺书

每一行测试代码,都是对用户的一份承诺:
“这个功能,我确认它在各种情况下都能正常工作。”

🧪 行动建议

  1. 今天就为一个工具函数写单元测试
  2. 明天为首页添加 Widget Test
  3. 下周配置 CI 自动运行测试

因为可靠的体验,始于一行测试,成于千次验证


附录:常用命令速查

场景 命令
运行单元测试 flutter test
生成覆盖率报告 flutter test --coverage && genhtml coverage/lcov.info -o coverage/html
运行 Widget Test flutter test test/widget/
运行集成测试(OH) flutter drive --target=integration_test/xxx.dart --platform=openharmony
查看连接设备 hdc list targets

没有测试的代码,如同没有护栏的悬崖——看似高效,实则危险。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐