
HarmonyOS 单元测试——从 LocalUnit.test 到 Ability.test一、测试在项目中的地位在 11 模块架构的英语学习 App 中测试是保障代码质量的关键手段。每个模块homePage、topicPage、minePage 以及 commonLib 等都包含了两种测试目录src/test/和src/ohosTest/。commons/commonLib/ └── src/ ├── test/ │ ├── List.test.ets # 测试列表入口 │ └── LocalUnit.test.ets # 本地单元测试 ├── ohosTest/ │ ├── ets/ │ │ └── test/ │ │ ├── Ability.test.ets # Instrumentation 测试 │ │ └── List.test.ets # 测试列表入口 │ └── module.json5这两种测试目录代表了 HarmonyOS 中两种不同的测试类型LocalUnitTest和InstrumentationTestohosTest。二、test 目录 vs ohosTest 目录src/test/目录LocalUnitTest运行在本地 JVM 上不依赖真机或模拟器只能测试纯 TypeScript/ArkTS 逻辑代码不能调用 kit API如 UI 组件、系统服务运行速度快适合频繁执行src/ohosTest/目录InstrumentationTest运行在真机或模拟器上可以测试完整的能力调用包括 UI 组件、系统 API需要打包安装到设备上运行运行速度慢通常作为 CI 流程的一部分选择原则纯逻辑测试如工具函数、模型计算放在 LocalUnitTest涉及 UI 渲染、系统 API 的测试放在 ohosTest。三、LocalUnitTest纯逻辑测试实践LocalUnitTest 适合测试 ViewModel 中的计算方法、数据模型的序列化/反序列化、工具函数的正确性。我们的项目中LocalUnit.test.ets文件的内容模板import{describe,beforeAll,beforeEach,afterEach,afterAll,it,expect}fromohos/hypium;exportdefaultfunctionlocalUnitTest(){describe(localUnitTest,(){beforeAll((){// 在所有测试用例之前执行一次});beforeEach((){// 在每个测试用例之前执行});afterEach((){// 在每个测试用例之后执行});afterAll((){// 在所有测试用例之后执行一次});it(assertContain,0,(){letaabc;letbb;expect(a).assertContain(b);expect(a).assertEqual(a);});});}这个模板使用了ohos/hypium测试框架这是 HarmonyOS 官方提供的轻量级测试框架。它提供了类似于 Jest 的 API 风格describe、it、expect。在实际项目中可以扩展的测试用例it(WordCard constructor test,0,(){constcardnewWordCard(1,apple,/ˈæpl/,n.,苹果,I eat an apple.,我吃了一个苹果。);expect(card.word).assertEqual(apple);expect(card.translation).assertEqual(苹果);expect(card.category).assertEqual(basic);});it(PreferenceUtil put and get,0,(){PreferenceUtil.getInstance(test).put(key,value);constresultPreferenceUtil.getInstance(test).get(key);expect(result).assertEqual(value);});需要注意的是PreferenceUtil 依赖ContextUtils和系统 Preferences API因此严格的本地单元测试无法测试它——这应该放在 ohosTest 中。四、InstrumentationTestUI 测试实践InstrumentationTest 运行在真机或模拟器上可以测试 UI 组件的创建和交互。Ability.test.ets的典型内容import{describe,it,expect}fromohos/hypium;import{Driver,ON}fromohos.UiTest;exportdefaultfunctionabilityTest(){describe(AbilityTest,(){it(test_page_load,0,async(){// 创建 UI 测试驱动letdriverDriver.create();awaitdriver.delayMs(1000);// 查找页面上的文字元素lettextawaitdriver.findComponent(ON.text(英语学习));expect(text!null).assertTrue();});});}InstrumentationTest 的核心能力UI 组件查找通过Driver查找页面上的组件按文本、ID、类型模拟用户操作点击、滑动、输入页面跳转验证验证路由跳转后的页面内容状态验证验证 State/Local 变量的变化五、ohosTest 中的测试组织每个模块的 ohosTest 目录结构一致features/homePage/src/ohosTest/ets/test/ ├── Ability.test.ets # 核心测试文件 └── List.test.ets # 测试列表注册所有测试套件List.test.ets的作用是汇总所有测试套件importabilityTestfrom./Ability.test;exportfunctionTestList(){abilityTest();}这样做的好处是新增测试文件时只需要在List.test.ets中注册即可module.json5中配置的入口文件保持不变。ohosTest目录下的module.json5配置了测试模块的信息{ module: { name: homePage_ohosTest, type: test, srcPath: , description: HomePage test module, testRunner: ohosTestRunner } }六、测试策略与覆盖率在 11 模块架构下建议的测试策略是核心逻辑全覆盖commonLib 中的 ManagerPreferenceUtil、NewWordManager、AudioPlayer和 UtilsLogger、ContextUtils应该有完整的 LocalUnitTest 覆盖关键页面 UI 测试homePage 的 MainPage、topicPage 的 WordCardPage、minePage 的 MinePage 应该有 InstrumentationTest验证页面加载和基本交互边界情况测试数据处理函数如数据序列化、生词本增删改查需要测试边界情况空数据、重复数据、大数据量构建集成在hvigorfile.ts中配置运行测试的任务CI/CD 流水线中自动执行七、总结HarmonyOS 的测试体系提供了 LocalUnitTest 和 InstrumentationTest 两种互补的方式。LocalUnitTestsrc/test/负责纯逻辑的快速验证InstrumentationTestsrc/ohosTest/负责真机环境下的集成测试。在我们的项目中每个模块都遵循这种双测试目录的结构为代码质量提供了基础保障。开发者应该根据测试目标选择合适的测试类型并且保持测试与代码的同步演进。