鸿蒙代码验证器使用文档
鸿蒙代码验证器(harmony-verify)在 DSH 里按需求文档验证鸿蒙应用的代码。它读取需求和工程源码,为每条需求编写 Harmony 单元测试和界面测试,写进工程的测试目录,在真机或模拟器上执行,然后逐条给出“满足、违反、未验证”的结论和证据。你允许修复时,它按失败修改生产代码,再用同一套测试全量复测,直到没有可以修复的失败为止。
它看得到代码:从源码找到页面、控件和状态,单元测试直接调用 ViewModel 核对内部结果,界面测试按源码里的文字和结构定位控件。只在界面上点一遍、看不到内部状态时容易漏掉的问题,也能测出来。
适用于按需求生成的鸿蒙应用(应用生成场景),以及从 Android 迁移来的鸿蒙应用(迁移场景)。只用于鸿蒙 Stage 工程。
使用前准备#
| 项 | 要求 |
|---|---|
| DSH | ^0.2.1-rc.2 |
| 工程 | 鸿蒙 Stage 工程根目录:有 build-profile.json5,至少一个模块有 src/main/module.json5 |
| 需求文档 | 文本格式的需求说明,例如 spec/spec.md;可以另给 Android 工程作为行为参照 |
| 鸿蒙工具链 | DevEco Studio 自带的 SDK、hvigor、ohpm 和 hdc |
| 设备 | 一台真机或模拟器,hdc list targets 能看到 |
| Node.js | 22.22 或更高 |
| Python | 3.11 或更高,界面测试使用,需要能导入 hypium 6.1.0.210 和 xdevice;启动 DSH 前把 DT_VERIFY_PYTHON 设为这个解释器的绝对路径 |
安装并启动 DSH。DSH 通过 npm 运行,装好 Node.js 后不需要单独安装。在终端里先把界面测试用的 Python 告诉 DSH,再启动 DSH 网页版:
export DT_VERIFY_PYTHON=/absolute/path/to/python3
npx @deepseek-ai/dsh web第一行换成你的 Python 解释器的绝对路径。DSH 默认在 http://127.0.0.1:3080 启动,并用默认浏览器打开页面;加 --no-open 只启动服务、不打开浏览器,端口被占用时加 --port <端口>。第一次使用时,打开「设置」→「模型」,填入 DeepSeek API 密钥并保存。
安装#
下面的录屏演示验证一个 demo 工程。
桌面版:打开「插件」→「发现」,在 Fuxi DSH 插件市场中找到“鸿蒙代码验证器”,点击安装。还没有「发现」时,先在「实验性插件」旁的「更多」中启用「自定义插件市场」,再添加索引源:
https://fuxi-ailabs.github.io/dsh-plugin-market/index.json命令行:先退出 DSH,再执行下面的命令(需要 PATH 上能找到 pnpm):
npx @deepseek-ai/dsh plugin --profile web add @fuxi-ailabs/dsh-dt-verifyweb 换成你使用的 profile。安装后插件注册 dt-verify Skill 和 5 个名称以“鸿蒙代码验证器子任务”开头的子 Agent 角色。这些角色只用于委派,不要用它们新建会话。
使用#
- 在 DSH 中把鸿蒙工程根目录作为工作区打开,确认设备(模拟器或测试真机)在线,
hdc list targets能看到。 - 在输入框输入
/dt-verify选中 Skill,再写上要验证的工程和需求文档,发送。路径和设备换成你自己的;只想验证、不改代码时,把“并修复发现的问题”改成“只验证,不修改生产代码”。
/dt-verify 验证当前鸿蒙工程并修复发现的问题。需求文档是 spec/spec.md,设备只用 127.0.0.1:5557。中途不用问我,跑完后告诉我运行目录、每条需求的结论、修复了什么和证据位置。- 验证器依次整理验收项、派子 Agent 编写测试、审查计划、上设备执行;有失败时生成失败包,修复后在新的运行里全量复测。整个过程不需要确认。“收益”一节的 3 个应用,每个用时 71–90 分钟。
- 结束后,回复里给出运行目录、链式汇总的路径、每条需求的结论和修复的改动。按下一节读结果。
读懂结果#
测试跑没跑成,和需求有没有被满足,是两个问题。汇总按验收要求分别给出:
| 用例状态 | 含义 |
|---|---|
PASS | 按计划执行,结果符合预期 |
FAIL | 执行了,结果与预期不符 |
BLOCKED | 缺少环境、设备或前置条件,或证据复核没有通过,没有得到有效结果 |
| 要求结论 | 含义 |
|---|---|
SATISFIED(满足) | 有充分证据表明要求被满足 |
VIOLATED(违反) | 有效证据表明要求被违反 |
UNVERIFIED(未验证) | 证据不足、执行受阻,或没有可观察的界面;不会被其他要求的通过补齐 |
测试写在工程里:单元测试在 entry/src/ohosTest/ets/test,界面测试在 entry/src/ohosTest/ui-scripts。运行目录里,acceptance.json 是验收要求,accepted-plan.json 是审查后冻结的正式计划,attempts/ 下是每次执行的用例状态、每一步的截图和控件树,最后一轮运行里的 chain-summary-*.json 是整次运行的最终交付。
有什么用#
| 能力 | 说明 |
|---|---|
| 每条需求都有结论 | 需求拆成带原文行号的验收要求,每条给出满足、违反或未验证,并附上截图、控件树和日志的位置 |
| 测试写进工程 | 单元测试和界面测试都写在工程的 ohosTest 目录里,可以随代码提交,以后再跑 |
| 先审计划,再执行 | 写好的测试由没有参与编写的审查者逐条接受或拒绝,接受的用例冻结以后才上设备执行 |
| 发现问题后修复 | 只改生产代码,不改测试;修复后用同一套测试全量复测,最多 5 轮 |
| 结论可以回查 | 每次执行单独留档,汇总时再按原始证据复核;执行受阻或证据不够的要求记为未验证,不算通过 |
验证原理#
一次完整的“验证并修复”按下面的流程进行。第 5 到第 8 步是修复循环,每一轮都在新的运行目录里复测,前一轮的证据保留不动。
它能测出问题,靠的是下面几种做法。例子来自一个按需求生成的电商应用。
| 做法 | 能测出什么 | 例子 |
|---|---|---|
| 每条用例绑定到需求原文 | 漏做或做错的功能 | 需求要求“登录时核对注册的凭据”,用例用未注册的手机号登录,应用却登录成功 |
| 状态刷新单独成类 | 页面已经打开时数据变化,页面还显示旧值;重新进入页面才正确的问题 | 购物车页开着时再加一次同一商品,条目数量仍是 1,底部合计已经是 2 件 |
| 单元测试直接调用业务代码 | 界面上不容易触发的逻辑分支 | 直接调用 UserViewModel.login,未注册账号应返回 false |
| 修复时不能改测试 | 为了通过而放宽断言、改测试 | 测试本身有问题时提出申诉,重新审查通过后才换用修订的用例 |
| 每轮全量复测 | 修好一处、改坏另一处 | 修好登录后,一条“不注册直接登录成功”的旧单元测试失败,被识别为测试问题并修订 |
什么时候用#
| 场景 | 得到什么 |
|---|---|
| 按需求生成鸿蒙应用以后 | 按需求文档逐条核对生成结果,不通过的功能直接修复,并留下可以重跑的测试 |
| Android 应用迁移到鸿蒙以后的验收 | 按需求文档逐条核对迁移结果,修复迁移中做错或漏掉的功能 |
| 功能开发完成后的自测和回归 | 改动以后按需求回归,确认没有把已有功能改坏 |
| 交付前核对 | 一份按需求逐条列出结论和证据的验收结果,可以直接交给评审 |
没有需求文档、不是鸿蒙 Stage 工程,或者主要功能依赖相机、华为账号这类模拟器不具备的能力时,用处不大。
限制#
分三类:模拟器上测不了、换真机可以补上的;真机上也测不了的;以及和设备无关的使用限制。“收益”一节的数据都是在模拟器上跑出来的。
模拟器不支持,真机支持
| 能力 | 模拟器上 | 真机上 |
|---|---|---|
| 相机拍照 | 调起系统相机后一直等待,不返回拍摄结果,记为未验证 | 相机可用;拍照界面属于系统相机,需要人工拍照后再验证后续功能 |
| 振动 | 没有马达,调用直接报错,记为未验证 | 能振动,但验证器目前读不到振动状态,仍需人工确认 |
| 端侧 AI 能力,例如 AI 字幕 | 接口不可用,没有回调,记为未验证 | 设备支持时可用,需要在真机上运行验证 |
| 碰一碰、发送到其他设备 | 不支持 | 需要两台真机,人工测试 |
在真机上运行时,设备要开启开发者模式,并能用 hdc list targets 看到;工程要配好签名,可以用 DevEco Studio 的自动签名。验证器在真机上的完整运行还没有验收。
真机上也测不了
| 情况 | 结果 |
|---|---|
| Canvas 绘制的内容,以及没有文字和 id 的图片、开关 | 定位不到,记为未验证 |
| 通知、提醒、后台任务等系统状态 | 读不到系统侧的状态,只能确认应用调用过接口,记为未验证 |
| 由系统分享目标完成的发送 | 在应用之外,只能确认分享面板被拉起 |
| 华为账号登录成功的路径 | 需要真实华为账号和应用的 AGC 配置,只验证登录入口和失败提示 |
| 显示问题,例如字形显示错误、颜色细节 | 用例按控件文字判断,看不到这类问题,可能判为通过 |
使用限制
| 情况 | 说明 |
|---|---|
| 运行时间 | 一个应用通常要 20–120 分钟,期间独占一台设备;同一个应用不要在同一台设备上同时跑两次 |
| 修复会改生产代码 | 建议在单独的分支上运行,结束后检查改动再合入 |
用上后的收益#
下面分两个场景给出初步数据:按需求生成的鸿蒙应用(应用生成场景),以及从 Android 迁移来的鸿蒙应用(迁移场景)。两个场景的运行方式和判定方式不同,每个场景先说明实验准备和实验设置,再给结果。
应用生成场景:测试检测与修复
实验准备
| 项 | 说明 |
|---|---|
| 应用 | 一批按需求文档用 ArkTS 从零生成的鸿蒙应用,每个应用都有需求文档(spec.md)和一份人工验收清单 |
| 修复前的结果 | 人工验收:按验收清单逐个功能点验收,记通过、失败或无法验证。验证器拿到的是人工验收时的同一版代码 |
| 选取范围 | 人工验收中有失败或无法验证功能点的应用共 18 个,目前跑完 9 个。其中 3 个修复后通过率提升,本节列出这 3 个;其余 6 个修复前后通过率不变 |
| 修复后的结果 | 修复后的代码装到设备上,按同一份验收清单逐项人工确认,确认修好的功能点才计入 |
实验设置
| 项 | 设置 |
|---|---|
| 插件 | 0.1.0-dev.28,与本页安装的 DSH 版本是同一套 Skill,在 DevEco Code 命令行中无人值守运行 |
| 模型 | deepseek-flash,推理强度 high |
| 输入 | 只给工程目录和需求文档,不给人工验收清单;提问要求验证并修复,中途不提问 |
| 设备 | 运行时用 nova 16 模拟器;修复后的确认在真机或模拟器上进行 |
| 运行方式 | 每个应用单独运行,跑到修复循环结束,最多 5 轮 |
结果
3 个应用的验收功能点通过率从 50 / 64(78.1%)提高到 58 / 64(90.6%),共修好 8 个功能点:
修好的 8 个功能点中,3 个由验证器自己测出并修好:文档扫描工具的“批量选择扫描记录”,传奇今生的“登录核对账号”和“重复加购时数量累加”。另外 5 个没有被单独测出失败,是验证器修复其他失败时一起修好的。修好的功能点都在设备上确认过:文档扫描工具在真机上,另外两个在模拟器上。每个应用用时 71–90 分钟,生产代码改动都很小(2–3 个文件,最多 +38 行)。没有测出的点主要是模拟器缺少的能力(相机、振动、账号)、没有可观察的界面(Canvas 绘制、系统分享)和显示问题。
迁移场景
实验准备
| 项 | 说明 |
|---|---|
| 应用 | Cofi、AntennaPod 两个从 Android 迁移到鸿蒙的应用 |
| 功能清单 | 人工整理的功能清单:Cofi 335 个功能点,AntennaPod 599 个(去重合并),每个功能点标为可用、部分可用或不可用 |
| 修复前的结果 | 迁移完成、还没有做验证修复的版本 |
| 判定方式 | 按功能清单逐条对照修复前后的产品代码判定可用性;界面测试修复的两组没有逐项装机复核 |
实验设置
| 项 | 设置 |
|---|---|
| 验证方式 | 分两种分别运行:只用界面测试验证并修复,或只用单元测试验证并修复;都只改生产代码 |
| 运行 | 界面测试修复在 Codex 上运行(gpt-6.1-sol,high);单元测试修复在 DevEco Code 上运行(deepseek-v4.1-flash) |
| 设备 | 鸿蒙模拟器 |
| 用时 | 界面测试修复:Cofi 6.4 小时,AntennaPod 8.8 小时;单元测试修复:AntennaPod 约 5.6 小时 |
结果
入口恢复的 131 个功能点,是入口或所在页面修好后能够进入,功能本身没有逐项验证。Cofi 的 34 个提升点里,有 29 个来自同一个问题:两个弹出面板的写法错误,导致面板弹不出来。