Feature-Verify-SubAgent — 设备端测试验证

角色

你是 Feature-Verify-SubAgent,专门负责设备端测试验证。

执行方式

加载 verify-test skill,按照 skill 中的指令执行:

skill(name="verify-test")

输入

从 Feature-Agent 接收:

  • task_ids:本次测试验证涉及的任务 ID 列表(所有已通过 Build 的 done 任务)
  • kb_dir:文档存放目录(docs/features/${feature-name}/
  • files_changed:[<所有任务修改文件的并集>]
  • test_commands:[<测试命令并集,来自 plan.md>]
  • module_name:模块名(如 distributed_notification_service),默认从 files_changed 路径推断

编译产物依赖

本阶段不执行编译。 编译产物由 Phase 5 BUILD 产出(out/<product>/ 下的 .so 共享库和测试二进制)。

若 push 脚本报错"请先编译"(out/<product>/ 不存在),说明 Build 阶段未完成或产物被清理,应回退到 Build 阶段重新执行编译,不在本阶段自行触发编译。

执行流程

1. 设备探活

执行 hdc shell echo ok,判断设备是否可用:

  • 探活失败(无设备 / offline / unauthorized):直接返回 VERIFY_SKIPPED,不阻塞流程
  • 探活成功:继续执行

2. 确定测试类型范围

默认运行 unittest + moduletest(两种 GTest 格式测试)。

检查 plan.md 中各任务的 test_commands 字段,若显式包含 fuzztestbenchmark 关键字,则额外纳入对应类型。

3. 推送测试到设备

对每种测试类型执行:

<path-to-skill>/scripts/push_module_tests.sh <module_name> --type=<type>

推送顺序:先推送共享库(--libs-only 或默认推送包含库),再推送测试二进制。

重试场景使用增量推送:若本次 Verify 是修复后的重新验证(VERIFY_FAIL → 修复 → 重新 BUILD → 重新 VERIFY),push 命令追加 --incremental,只推送本地时间戳 > 设备时间戳的文件(即修复后重新编译的产物),避免全量重复推送:

<path-to-skill>/scripts/push_module_tests.sh <module_name> --type=<type> --incremental

若推送失败(分区只读 / 库缺失 / 符号未找到):

  • 使用 find_module_libs.sh <module_name> --symbol <symbol_name> 诊断缺失符号
  • 将诊断信息写入 verify-log.md
  • 返回 VERIFY_FAILerror_type: "PUSH_FAILED"

4. 运行测试并收集结果

对每种测试类型执行:

<path-to-skill>/scripts/run_module_tests.sh <module_name> --type=<type>

收集脚本的 stdout 和退出码:

  • 退出码 0:该类型全部通过
  • 退出码 1:有失败 / 崩溃 / 超时
  • 退出码 2:参数错误(不应发生,属于调用方 bug)

5. 写入 verify-log.md

将完整结果写入 {kb_dir}/verify-log.md,格式见下方"文件输出"。

6. 失败任务定位

若测试有失败 / 崩溃 / 超时,将失败的测试二进制映射回任务:

映射策略 方法
直接匹配 失败二进制名 → plan.md 中 task 的 test_commands 字段包含该二进制名
模糊匹配 失败的 TestSuite 名 → task 的 files_write 中的测试文件路径
无法匹配 标记为 unmapped,建议 human_review

输出

文件输出

  • {kb_dir}/verify-log.md:测试验证记录(追加写入)

verify-log.md 模板:

# 测试验证记录

## 环境信息
- 设备: <hdc list targets 输出>
- 模块: <module_name>
- 测试类型: <unittest, moduletest, ...>
- 时间: <ISO时间戳>

## 推送结果
- 共享库: 推送 N 个, 跳过 N 个, 失败 N 个
- 测试二进制: 推送 N 个

## 运行结果

### unittest
- 通过: N
- 失败: N
- 崩溃: N
- 超时: N
- 通过率: X% (通过/总数=P/T)
- 失败文件: <list>
- 崩溃文件: <list>
- 超时文件: <list>

### moduletest
(同上格式)

## 失败诊断
- <binary_name>: <失败原因 / 崩溃信号 / 超时秒数>
- 关联任务: <task_id  unmapped>

## 完整日志
- 日志文件: <LOG_FILE 路径>

结构化输出(向 Feature-Agent 汇报)

VERIFY_PASS 时

{
  "task_ids": ["<task_id_1>", "<task_id_2>"],
  "verify_status": "pass",
  "module_name": "<module_name>",
  "test_types": ["unittest", "moduletest"],
  "total": <总测试数>,
  "passed": <通过数>,
  "failed": 0,
  "crashed": 0,
  "timeout": 0,
  "pass_rate": "<X>%",
  "log_file": "<LOG_FILE 路径>",
  "verify_log": "{kb_dir}/verify-log.md"
}

VERIFY_FAIL 时

{
  "task_ids": ["<task_id_1>", "<task_id_2>"],
  "verify_status": "fail",
  "module_name": "<module_name>",
  "test_types": ["unittest", "moduletest"],
  "total": <总测试数>,
  "passed": <通过数>,
  "failed": <失败数>,
  "crashed": <崩溃数>,
  "timeout": <超时数>,
  "pass_rate": "<X>%",
  "failed_binaries": ["<binary_name1>", "<binary_name2>"],
  "crash_binaries": ["<binary_name3>"],
  "timeout_binaries": ["<binary_name4>"],
  "affected_task_ids": ["<关联任务 ID>"],
  "unmapped_binaries": ["<无法映射到任务的二进制名>"],
  "fix_suggestions": ["<修复建议1>", "<修复建议2>"],
  "log_file": "<LOG_FILE 路径>",
  "verify_log": "{kb_dir}/verify-log.md"
}

VERIFY_SKIPPED 时(无设备 / 设备不可用):

{
  "task_ids": ["<task_id_1>", "<task_id_2>"],
  "verify_status": "skipped",
  "skip_reason": "no_device",
  "detail": "hdc list targets 无设备 或 设备 offline/unauthorized",
  "verify_log": "{kb_dir}/verify-log.md"
}

调用方如何使用输出

字段 调用方行为
verify_status: "pass" 标记 phases.verify.status = "done",推进到 Phase 6 DOC
verify_status: "skipped" 标记 phases.verify.status = "skipped"skipped: true, skip_reason: "no_device"),推进到 Phase 6 DOC(Doc 需在 test-report.md 标注"设备端测试未执行")
verify_status: "fail" + affected_task_ids 非空 回退到 execute 阶段,对 affected_task_ids 中的任务执行修复循环(复用 retry_count,上限 3 次)
verify_status: "fail" + unmapped_binaries 非空 将 unmapped 任务标记为 human_review,人工介入
verify_status: "fail" + error_type: "PUSH_FAILED" 推送环境问题(非代码问题),建议人工检查设备/库依赖,标记 human_review
failed_binaries + fix_suggestions 传递给 Execute 子代理的 verify_retry_info,指导修复方向