超越简单测试:深入Griewank函数,看它如何‘刁难’粒子群算法(PSO)
2026/6/2 19:04:22
作者:晚霞的不甘
日期:2025年12月5日
标签:Flutter · OpenHarmony · 自动化测试 · 单元测试 · 集成测试 · E2E 测试 · CI/CD · 鸿蒙生态
在 OpenHarmony 多设备、高安全、强审核的生态下,一次线上缺陷可能导致全端下架:
手动测试无法覆盖:
本文将构建一套分层自动化测试体系,覆盖Dart 逻辑、原生插件、跨设备协同、UI 交互四大维度,助你实现:
┌───────────────────────┐ │ E2E 测试 (5%) │ ← DevEco UI Test / Flutter Driver ├───────────────────────┤ │ 集成测试 (15%) │ ← Mock 原生通道 + 真实业务流 ├───────────────────────┤ │ 单元测试 (80%) │ ← flutter test + mockito └───────────────────────┘| 测试类型 | 工具 | 运行速度 | 适用场景 |
|---|---|---|---|
| 单元测试 | flutter test | < 1s | 纯 Dart 逻辑(如状态管理、工具函数) |
| 集成测试 | flutter test+ Mock | 2–5s | 调用 MethodChannel 的业务逻辑 |
| UI 测试 | Flutter Driver | 10–30s | 页面跳转、表单提交、列表滚动 |
| 多端 E2E | DevEco UI Test | 30–60s | 跨设备任务迁移、分布式数据同步 |
// lib/utils/health_calculator.dartdoublecalculateAvgHeartRate(List<int>rates){if(rates.isEmpty)throwArgumentError('Rates cannot be empty');returnrates.reduce((a,b)=>a+b)/rates.length;}// test/utils/health_calculator_test.dartimport'package:test/test.dart';import'package:my_app/utils/health_calculator.dart';voidmain(){test('calculateAvgHeartRate returns correct average',(){expect(calculateAvgHeartRate([60,70,80]),equals(70.0));});test('calculateAvgHeartRate throws on empty list',(){expect(()=>calculateAvgHeartRate([]),throwsA(isA<ArgumentError>()));});}# 运行测试fluttertest# 生成覆盖率报告fluttertest--coverage genhtml coverage/lcov.info -o coverage/html✅目标:核心模块覆盖率 ≥ 80%
// test/integration/health_service_test.dartimport'package:flutter/services.dart';import'package:mockito/mockito.dart';classMockMethodChannelextendsMockimplementsMethodChannel{}voidmain(){late MockMethodChannel mockChannel;late HealthService service;setUp((){mockChannel=MockMethodChannel();// 注入 Mock 通道when(mockChannel.invokeMethod('readHeartRate')).thenAnswer((_)async=>72);service=HealthService(channel:mockChannel);});test('getHeartRate returns mocked value',()async{finalrate=awaitservice.getHeartRate();expect(rate,equals(72));verify(mockChannel.invokeMethod('readHeartRate')).called(1);});}when(mockChannel.invokeMethod('readHeartRate')).thenThrow(PlatformException(code:'PERMISSION_DENIED'));expectLater(service.getHeartRate(),throwsA(isA<HealthPermissionException>()),);// test_driver/app_test.dartimport'package:flutter_driver/flutter_driver.dart';import'package:test/test.dart';voidmain(){group('Health App E2E',(){finalheartRateFinder=find.byValueKey('heart_rate_display');finalstartButton=find.byValueKey('start_monitoring');FlutterDriver driver;setUpAll(()async{driver=awaitFlutterDriver.connect();});tearDownAll(()async{if(driver!=null)awaitdriver.close();});test('shows heart rate after start',()async{awaitdriver.tap(startButton);awaitdriver.waitFor(heartRateFinder);finaltext=awaitdriver.getText(heartRateFinder);expect(text,matches(RegExp(r'\d+ bpm')));});});}# 构建 profile 包flutter build ohos --profile# 安装并运行测试hdcinstallbuild/ohos/profile/outputs/default/entry-default-signed.hap flutter drive --target=test_driver/app_test.dart⏱️提示:使用
--no-sound-null-safety若插件不支持空安全
使用DevEco Studio UI Test(基于 JUnit + ArkTS):
// ohosTest/HealthSyncTest.etsimport{describe,it,expect}from'@ohos/test';@Describe('Health Data Sync')classHealthSyncTest{@It('should sync heart rate to wearable')asynctestSyncToWearable(){// 1. 在手机端启动监测awaitthis.launchAppOnDevice('phone');awaitthis.clickButton('start_monitoring');// 2. 等待手表端接收数据awaitthis.launchAppOnDevice('watch');constrate=awaitthis.getText('latest_heart_rate');// 3. 验证数据一致expect(rate).toMatch(/\d+ bpm/);}}hdc -t <device_id>指定操作目标设备# .gitlab-ci.ymlstages:-test-e2eunit_test:stage:testscript:-flutter test--coverage-genhtml coverage/lcov.info-o coverage/artifacts:paths:[coverage/]ui_test_phone:stage:e2escript:-flutter build ohos--profile-hdc install...-flutter drive--target=test_driver/app_test.darttags:[ohos_device]ui_test_watch:stage:e2escript:-./run_dev_evo_test.sh HealthSyncTesttags:[ohos_wearable]✅ 所有新功能必须附带单元测试
✅ 核心用户路径(如登录、支付)100% E2E 覆盖
✅ 每次 PR 触发 CI 全量回归
✅ 多设备组合测试每周执行一次
✅ 异常场景(权限拒绝、网络中断)纳入测试用例
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Flutter Driver 找不到元素 | 未设置key | 为 Widget 添加ValueKey('xxx') |
| 真机测试超时 | 设备未授权调试 | 执行hdc kill重连 |
| 多设备测试不同步 | 时间未校准 | 使用 NTP 同步设备时间 |
| 覆盖率不准确 | 未排除 generated 文件 | 在lcov中添加-e "*/*.g.dart" |
没有自动化的质量保障:
🧪行动建议:
- 今天就为一个工具函数写单元测试
- 明天为登录流程添加 Flutter Driver 脚本
- 下周在 CI 中集成覆盖率报告
因为每一次自信的点击“发布”,都源于背后千次自动验证。
附录:测试工具速查
| 工具 | 用途 | 文档 |
|---|---|---|
flutter test | 单元/集成测试 | https://docs.flutter.dev/testing |
| Flutter Driver | UI 自动化 | https://docs.flutter.dev/testing/integration-tests |
| DevEco UI Test | 多端 E2E | https://developer.huawei.com/consumer/cn/doc/development/Testing-Guides |
| OhTestRunner | OpenHarmony 测试框架 | https://gitee.com/openharmony/xts_acts |
测试不是找 Bug,而是证明软件值得被信任。