AgentSkillsCN

ohtest

OpenHarmony 单元测试补全技能。1) 根据 .d.ts 接口定义生成 ohosTest 测试套(ohtest.py):针对接口方法的 4 类边界用例。2) 根据 .ets 页面文件生成 UITest 套件(uitest_gen.py):为页面内的每个控件、布局和动作分别生成 UI 测试用例,使用 @kit.TestKit 的 Driver/ON、abilityDelegatorRegistry,并参考 HarmonyOS UITest 指南。

SKILL.md
--- frontmatter
name: ohtest
description: "OpenHarmony 单元测试补全技能。1) 根据 .d.ts 接口定义生成 ohosTest 测试套(ohtest.py):接口方法 4 类边界用例。2) 根据 .ets 页面文件生成 UITest 套件(uitest_gen.py):对页面内每个控件、布局和动作分别生成 UI 测试用例,使用 @kit.TestKit 的 Driver/ON、abilityDelegatorRegistry,参考 HarmonyOS UITest 指南。"
author: "Created by user"
created: "2026-01-28"
version: "1.0.0"

OpenHarmony 单元测试补全技能 (ohtest)

根据 .d.ts 接口文件(如 NAPI 生成的 Index.d.ts)在 ohosTest 的 test 文件夹下自动补全单元测试套件,参照 Ability.test.ets 结构,以接口为测试对象,生成符合 Hypium 规范的测试用例。

功能说明

  • 输入:接口定义文件(如 entry/src/main/cpp/types/libentry/Index.d.ts)、测试目录(如 entry/src/ohosTest/ets/test)、可选模块导入名(如 libentry.so)。
  • 输出:在 test 目录下新增一个 *Test.test.ets 文件,并在现有 List.test.ets(或主测试入口)中注册该测试套。
  • 命名规则:接口文件名去掉特殊符号 + Test。例如 Index.d.tsIndexdtsTest;函数名为 indexdtsTest(),describe 套件名为 IndexdtsTest
  • 测试套结构:与 Ability.test.ets 一致:
    • export default function <name>Test() {
    • describe('<Name>Test', () => { ... })
    • 默认包含 beforeAllbeforeEachafterEachafterAll
    • 每个接口方法对应多组 it('<method>_tc_N', 0, () => { ... })

四类边界测试用例

对每个 .d.ts 中的导出接口方法,生成 4 个用例:

类型说明示例(以 add(a: number, b: number) => number 为例)
正常值各种允许的输入类型、典型值add(1, 2)expect(result).assertEqual(3)
最大值输入类型的最大值add(Number.MAX_SAFE_INTEGER, 0),断言与预期一致
最小值输入类型的最小值add(Number.MIN_SAFE_INTEGER, 0) 或负值边界
异常/压力非数据类型、转换或大量调用如 1000 次 add(1, 1),每次 expect(...).assertEqual(2)

用例内调用接口方法,并用 expect(返回值).assertEqual(预期值)(或 assertContain 等)做断言。

代码结构与编码规范

生成测试用例时需遵守以下约定,本技能在生成代码时已落实基础实现。

代码结构

  • 公共常量:测试中使用的数值、字符串等常量应集中在 constant.ets 中定义并导出,测试文件通过 import { ... } from './constant' 引用。生成器在首次生成前会检查 test 目录下是否存在 constant.ets,若不存在则自动创建并写入最小常量集(如 HILOG_DOMAINTEST_FILTERVAL_0VAL_3STRESS_1000MAXMIN 等),后续可手动扩展。

编码规范

  1. 行宽:单行不超过 120 字符;过长注释或表达式应换行。
  2. 用例间隔:每个 it() 用例块之间保留一个空行,便于阅读与 diff。
  3. 魔数:代码中不直接写魔数(如 0x000001000),改用 constant.ets 中的常量名(如 HILOG_DOMAINTEST_FILTERSTRESS_1000)。
  4. 文件拆分:单个测试文件若超过 2000 行,应拆分为多个文件(如 Indexdts_test_1.etsIndexdts_test_2.ets),并在主入口中按序引入;生成器目前不自动拆分,需人工处理超大文件。

生成内容已做到:使用 constant.ets 与导入常量、it() 间空行、hilog/expect 使用常量名、注释控制行宽;更多常量或拆分逻辑可在生成后手动补充。

UITest(页面 UI 测试)

根据 .ets 页面文件(如 pages/Index.ets)在 ohosTest 的 test 目录下生成 UI 测试套件,实现对页面的单元级 UI 测试。参考 HarmonyOS UITest 指南arkXtest User Guide

功能说明

  • 输入:页面 .ets 文件路径(如 entry/src/main/ets/pages/Index.ets)、测试目录(如 entry/src/ohosTest/ets/test)、可选 Ability 名称(默认 EntryAbility)。
  • 输出:在 test 目录下新增 <StructName>Ui.test.ets(如 IndexUi.test.ets),并在 List.test.ets 中注册该测试套。
  • 解析内容:从页面中解析 struct 名、@State 初始文本、Text(this.xxx) / Text('literal').onClickthis.xxx = 'yyy'、以及 Row() / Column() 布局。
  • 生成用例
    • 页面加载:断言当前 Top Ability 为指定 Ability。
    • 布局:断言存在 Row / ColumnON.type('Row') / ON.type('Column'))。
    • 控件:对每个初始显示的文本断言存在(ON.text('...')assertComponentExist)。
    • 动作:对每个带 onClick 且会改变 @State 的控件,生成「findComponent → click → assertComponentExist(变化后文本)」用例。
  • 框架:使用 @kit.TestKitDriverONabilityDelegatorRegistry,以及 @ohos/hypiumdescribe / it / expect;常量从 constant.ets 引入(TEST_FILTERUI_DELAY_MS)。

何时使用

  • 用户说:「对 Index.ets 实现 UI 测试」「为页面生成 UITest」「根据页面控件和布局写 UI 单元测试」。
  • 需要对 ArkUI 页面做自动化 UI 测试:页面加载、布局存在、控件存在、点击后状态/文案变化。

使用方式

bash
# 必选:页面 .ets 文件、测试目录;可选:Ability 名、是否更新 List.test.ets
python3 src/skills/ohtest/uitest_gen.py \
  --ets /path/to/entry/src/main/ets/pages/Index.ets \
  --test-dir /path/to/entry/src/ohosTest/ets/test \
  [--ability-name EntryAbility] \
  [--no-update-list]

生成文件命名:<StructName>Ui.test.ets(如 IndexUi.test.ets),套件名为 <StructName>UiTest(如 IndexUiTest)。若 test 目录下已有 constant.ets,生成器会追加 UI_DELAY_MS(若缺失),与 dts 单元测试共用同一 constant 文件。

参照与限制

  • 参照HarmonyOS UITest 指南arkXtest UiTest(Driver.create、findComponent(ON.text)、click、assertComponentExist)。
  • 限制:解析基于简单正则,仅识别 @State 字符串、Text(this.xxx) / Text('literal').onClickthis.xxx = 'yyy'Row() / Column();复杂表达式或动态文本需生成后人工补充用例。

何时使用(dts 单元测试)

  • 用户说:「根据 Index.d.ts 补全/生成单元测试」「为 libentry 接口写测试」「在 ohtest 里增加以 .d.ts 为对象的测试套」。
  • 需要以 NAPI/TS 接口为对象,在 ohosTest 下快速生成符合规范的边界测试用例时。

使用方式(dts 单元测试)

bash
# 必选:接口定义文件、测试目录;可选:模块名(默认 libentry.so)、是否更新 List.test.ets
python3 src/skills/ohtest/ohtest.py \
  --dts /path/to/entry/src/main/cpp/types/libentry/Index.d.ts \
  --test-dir /path/to/entry/src/ohosTest/ets/test \
  [--module libentry.so] \
  [--no-update-list]

生成文件命名:<基名>.test.ets,基名为接口文件名去掉特殊符号(如 Index.d.tsIndexdts),故得 Indexdts.test.ets;套件名为基名+Test(如 IndexdtsTest),describe 与 export default function 分别为 IndexdtsTestindexdtsTest

参照模板

  • 结构参照:Ability.test.etsexport default function abilityTest()describe('ActsAbilityTest', () => { ... })、beforeAll/beforeEach/afterEach/afterAll、it('assertContain', 0, () => { ... expect(...).assertEqual(...) }))。
  • 测试对象:来自 Index.d.ts 的导出接口(如 add),导入方式与工程一致(如 import lib from 'libentry.so',调用 lib.add(...))。

Fuzz 测试执行(fuzztest.py)

在正确的工作目录和环境(含 hdc 路径)下调用 developer_test 的 start.sh 执行 FUZZ 测试套。

环境与路径

  • 工作目录:执行时在 test/testfwk/developer_test 下调用 ./start.sh
  • hdc:框架通过 shutil.which("hdc") 查找 hdc。脚本会将 ${OHOS_SDK_PATH}/linux/toolchains(及 toolchains/bin 若存在)加入 PATH,以便框架找到 hdc;未设置 OHOS_SDK_PATH 时需保证系统 PATH 中已有 hdc。
  • DEVTESTDIR:脚本会设置 DEVTESTDIR 为 developer_test 的绝对路径,与框架约定一致。

何时使用

  • 用户说:「执行 GetAppStatsMahFuzzTest 的 fuzz 测试」「跑 FUZZ 用例」「执行 fuzztest」。
  • 需要在本机通过 developer_test 框架在设备上跑指定 FUZZ 测试套时。

使用方式

bash
# 必选:-ts 测试套名;可选:-p 产品名、--coverage、--dry-run
python3 src/.claude/skills/ohtest/fuzztest.py run -ts GetAppStatsMahFuzzTest
python3 src/.claude/skills/ohtest/fuzztest.py run -ts GetAppStatsMahFuzzTest -p rk3568 --coverage
python3 src/.claude/skills/ohtest/fuzztest.py run -ts GetAppStatsMahFuzzTest --dry-run
python3 src/.claude/skills/ohtest/fuzztest.py help
参数说明
-ts / --testsuite测试套名(必填),如 GetAppStatsMahFuzzTest
-p / --product产品名,默认 rk3568
--coverage附加 -cov coverage 收集覆盖率
--dry-run仅打印将要执行的命令,不实际执行

执行前需:设备已连接、hdc 可用(设置 OHOS_SDK_PATH 或系统 PATH 中含 hdc)。


分析 fuzztest 测试覆盖率(coverage_analysis.py)

对已跑过带覆盖率 fuzz 测试的设备,收集 gcda、生成 .gcov 并统计覆盖率。

流程

  1. 在设备上跑带覆盖率的 fuzz 测试(若尚未跑过)
    python3 src/.claude/skills/ohtest/fuzztest.py run -ts GetAppStatsMahFuzzTest --coverage
  2. 收集覆盖率并生成报告
    python3 src/.claude/skills/ohtest/coverage_analysis.py run [-p rk3568]
    会从设备上两个路径查找 *.gcda:① 本地根(由本地路径前两级推导,如 /root/ohos);② /data/gcov/<本地根>(如 /data/gcov/root/ohos)。拷贝到 reports/obj 后,再拷贝对应 *.gcno 与源码,在 reports/obj 内执行 gcov。
  3. 查看覆盖率统计
    python3 src/.claude/skills/ohtest/coverage_analysis.py analyze
    解析 reports/obj 下的 .gcov 并输出可执行行、已覆盖行、覆盖率百分比及等级。

环境

  • hdc:与 fuzztest 相同,脚本会将 ${OHOS_SDK_PATH}/linux/toolchains(及 toolchains/bin)加入 PATH;未设置时需保证系统 PATH 中已有 hdc。
  • 执行 run 前需设备已连接且已跑过带 -cov coverage 的 fuzz 测试。

技能 1:清除分析结果并再次分析

清除 reports/obj 下的覆盖率相关文件(.gcda、.gcno、.cpp、.gcov),再从设备拉取 gcda、拷贝 gcno/cpp、执行 gcov,最后执行 analyze 输出统计。

bash
python3 src/.claude/skills/ohtest/coverage_analysis.py clear-analyze
python3 src/.claude/skills/ohtest/coverage_analysis.py clear-analyze -p rk3568

技能 2:清除分析结果、重新运行 fuzztest 并分析

先清除 reports/obj;再在设备上执行带覆盖率的 fuzz 测试(调用 fuzztest.py);然后从设备拉取 gcda、生成 .gcov;最后执行 analyze 输出统计。

bash
python3 src/.claude/skills/ohtest/coverage_analysis.py clear-rerun-fuzz-analyze
python3 src/.claude/skills/ohtest/coverage_analysis.py clear-rerun-fuzz-analyze -ts GetAppStatsMahFuzzTest -p rk3568
参数说明
-ts / --testsuitefuzz 测试套名,默认 GetAppStatsMahFuzzTest
-p / --product产品名,默认 rk3568
--device指定设备 ID
--search-root设备上查找 *.gcda 的目录,可多次指定