渐进式编程课
鸿蒙 目录
第 34 课2026.08.19

适用场景:同一个异步服务需要覆盖多组成功与失败输入,且希望失败报告能直接定位具体参数场景

第 34 课:Hypium 异步参数化测试

  • 日期:2026-08-19
  • 课程序号:第 34 课
  • 知识点:为每组异步参数注册独立用例,并用 await 等待 Promise 完成
  • 适用场景:同一个异步服务需要覆盖多组成功与失败输入,且希望失败报告能直接定位具体参数场景

承接上一课:上一课用测试用例工厂为同步边界参数生成独立的 it;本课把同一结构扩展到 Promise 场景,确保每个异步用例真正等待结果后再结束。

核心概念

  • 用例工厂注册的回调要标记为 async,并在 Act 阶段 await 被测 Promise。
  • 成功和失败参数仍应生成独立用例,参数只描述输入、预期结果与行为名称。
  • 验证失败场景时要确认 Promise 确实被拒绝;不能只写 try/catch 后无条件通过。
  • 不要在一个 it 内循环执行多组异步断言,否则首个失败会掩盖后续参数场景。

最小 ArkTS / Hypium 示例

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

interface LoadCase {
  name: string;
  userId: number;
  expectedName: string;
}

class UserService {
  async loadName(userId: number): Promise<string> {
    return Promise.resolve(`用户${userId}`);
  }
}

function registerLoadCase(testCase: LoadCase): void {
  it(testCase.name, 0, async () => {
    // Arrange
    const service: UserService = new UserService();

    // Act
    const actual: string = await service.loadName(testCase.userId);

    // Assert
    expect(actual).assertEqual(testCase.expectedName);
  });
}

export default function userServiceAsyncParameterizedTest(): void {
  describe('UserService.loadName', () => {
    const cases: LoadCase[] = [
      { name: 'returnsNameForFirstUser', userId: 1, expectedName: '用户1' },
      { name: 'returnsNameForSecondUser', userId: 2, expectedName: '用户2' }
    ];

    cases.forEach((testCase: LoadCase) => {
      registerLoadCase(testCase);
    });
  });
}

两个 it 都会等待各自的 loadName() 完成。若遗漏 await,用例可能在 Promise 得出结果之前结束,异步失败也可能无法归属到正确用例。

3~5 分钟练习

给参数表增加输入 userId: 3,预期结果为 用户3,并使用行为化名称 returnsNameForThirdUser。不要修改 UserService 或把新断言写进已有用例。

参考答案

ts
const cases: LoadCase[] = [
  { name: 'returnsNameForFirstUser', userId: 1, expectedName: '用户1' },
  { name: 'returnsNameForSecondUser', userId: 2, expectedName: '用户2' },
  { name: 'returnsNameForThirdUser', userId: 3, expectedName: '用户3' }
];

重新运行测试后应看到三个独立用例;每个用例都通过工厂内的 await 等待自己的异步结果。

与上一课的联系

上一课建立了“每组参数对应一个独立用例”的结构;本课保留该结构,并为用例回调加入 async/await,把同步参数化测试推进到可正确验证 Promise 的异步场景。