在这里插入图片描述

HarmonyKit | 鸿蒙新特性:hypium 测试框架与工具函数单元测试实践

引言:为什么工具应用更需要测试

工具应用不像社交或电商 App 有复杂的业务流程和状态变化。它的核心逻辑简单:输入 → 算法 → 输出。但恰恰因为简单,如果算法出错了——用户得到错误的结果而无法察觉——后果比 UI 崩溃严重得多。Base64 的 encode→decode 必须回到原始输入。HEX→RGB→HEX 的双向转换必须精确。如果这些基本算法出错,用户信任会瞬间崩塌。

HarmonyKit 的测试策略是:只测 utils 层,不测 UI 层。 因为工具应用的核心价值在算法正确性——算法对了,UI 展示正确结果的概率极高。

项目仓库:https://atomgit.com/VON-/harmony-kit

hypium 基础

hypium 是鸿蒙官方的 JavaScript/ArkTS 测试框架。HarmonyKit 在 oh-package.json5 中声明:

"devDependencies": {
  "@ohos/hypium": "1.0.25",
  "@ohos/hamock": "1.0.0"
}

在这里插入图片描述

测试入口文件 LocalUnit.test.ets 负责执行所有测试套件。基本结构:
在这里插入图片描述

import { describe, it, expect } from '@ohos/hypium';

export default function testsuite() {
  describe('Base64Utils', () => {
    it('encode_hello', () => {
      let result = Base64Utils.encode('hello');
      expect(result).assertEqual('aGVsbG8=');
    });
  });
}

describe 定义测试组(通常一个 utils 类一个 describe)。it 定义单个测试用例(格式为 it('用例描述', callback))。expect 提供断言行:assertEqual(严格相等)、assertContain(包含子串)、assertTrue/assertFalse(布尔断言)、assertNull(null 检查)。

核心测试场景

Base64Utils:往返测试

it('encode_decode_roundtrip_ascii', () => {
  let original = 'Hello, HarmonyKit!';
  let encoded = Base64Utils.encode(original);
  let decoded = Base64Utils.decode(encoded);
  expect(decoded).assertEqual(original);
});

it('encode_decode_roundtrip_chinese', () => {
  let original = '你好,鸿蒙!';
  let encoded = Base64Utils.encode(original);
  let decoded = Base64Utils.decode(encoded);
  expect(decoded).assertEqual(original);
});

任何输入经过 encode→decode 后必须回到原始值。中文字符测试尤其重要——如果 TextEncoder 和 TextDecoder 的编码不一致(如编码用 utf-8 解码用 utf-16),中文会乱码。往返测试能捕获这类错误。

JsonUtils:正常、错误和边界

it('format_valid_json', () => {
  let input = '{"name":"test","value":42}';
  let result = JsonUtils.format(input, 2);
  expect(result).assertContain('"name"');
  expect(result).assertContain('"value"');
  expect(result).assertContain('\n  '); // 有缩进
});

it('validate_broken_json', () => {
  let result = JsonUtils.validate('{broken');
  expect(result.valid).assertFalse();
});

it('compress_removes_all_whitespace', () => {
  let result = JsonUtils.compress('{"a": 1, "b": 2}');
  expect(result).assertEqual('{"a":1,"b":2}');
});

格式化和压缩测试断言具体输出值。校验测试只断言 validerror 的逻辑正确性。

ColorUtils:转换精度

it('hex_to_rgb_to_hex_roundtrip', () => {
  let hex = '#007aff';
  let rgb = ColorUtils.hexToRgb(hex);
  let result = ColorUtils.rgbToHex(rgb.r, rgb.g, rgb.b);
  expect(result).assertEqual('#007AFF');
});

it('rgb_to_hsl_known_values', () => {
  let hsl = ColorUtils.rgbToHsl(255, 0, 0); // 纯红
  expect(hsl.h).assertEqual(0);    // 色相0或360
  expect(hsl.s).assertEqual(100);  // 饱和度100%
  expect(hsl.l).assertEqual(50);   // 明度50%
});

颜色转换涉及浮点运算的精度问题——往返转换的误差必须控制在合理范围内。已知值测试(纯红的 HSL 应该是 0°, 100%, 50%)验证算法的正确性。

HashUtils:已知答案测试

it('md5_hello_world', async () => {
  let result = await HashUtils.hash('hello', 'MD5');
  expect(result).assertEqual('5d41402abc4b2a76b9719d911017c592');
});

it('sha256_empty_string', async () => {
  let result = await HashUtils.hash('', 'SHA256');
  expect(result).assertEqual('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
});

MD5("hello")SHA256("") 的哈希值在密码学社区是公认的。任何合格的实现都必须输出这些值。这是算法验证的"金标准"——用已知输入和已知输出来测试实现。

边界测试

it('base64_encode_empty_string', () => {
  expect(Base64Utils.encode('')).assertEqual('');
});

it('url_decode_invalid_sequence', () => {
  // 测试对残缺百分号序列的处理
});

it('hash_very_long_input', async () => {
  let input = 'a'.repeat(10000); // 10000 字符
  let result = await HashUtils.hash(input, 'MD5');
  expect(result.length).assertEqual(32); // MD5 = 32 hex chars
});

空字符串、超长输入、不合法序列——这些边界情况如果都通过,基本算法的正确性就有了很高保障。

测试局限性

只测 utils 层,不测 UI 层。原因:鸿蒙的组件测试框架在当前版本成熟度不够,且工具应用核心价值在算法——算法对了 UI 展示正确结果的概率极高。UI 测试更适合在项目达到一定规模且有成熟的鸿蒙组件测试工具后再引入。

项目仓库:https://atomgit.com/VON-/harmony-kit

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐