Skip to content

[Docs] 仓库质量文档 #385

Description

@jing-gou

背景

仓库的测试结论分布在 CMake、Python/Gateway 测试入口、CI workflow 和 HIL 脚本中。需要一个以“测试证明了什么、没有证明什么”为核心的质量文档,方便贡献者和 Review 者判断改动的验证范围。

目标

更新 docs/engineering/repository-quality.md,按测试模块说明当前覆盖情况,并将 CI 项目单独成章。文档不把测试数量或覆盖率门槛误写成产品行为已经全面验证。

已记录的测试结论

  • C++ Host unit:tests/host 注册 94 个 CTest,其中 90 个带 unit 标签;基线运行 94/94 通过。覆盖 schedule、timing、IM、MCP、storage、voice、display、board 和 runtime 等 Host 可测模块。
  • C++ Host integration:4 个 integration CTest,覆盖 Host runtime 装配及 SQLite repository/schema/schedule rule 组合行为;基线运行全部通过。
  • IM Gateway TypeScript:33 个 test/*.test.mjs 文件,另有 test/run-tests.mjs contract runner,覆盖 application、HTTP/SSE、持久化、渠道适配器、投递/outbox、配对、action UI 和安全边界。
  • Python:18 个测试模块,覆盖固件/Profile、设备配置、E2E runner/evidence、契约检查和 SQLite probe;基线运行 198 个用例,1 个跳过,整体通过。
  • 双端契约:共享 fixture 同时由 C++ 和 TypeScript 引用,并由 check_contract_dual_end.py 做静态引用检查;该检查不等同于运行时覆盖率。
  • Host E2E:PR CI 运行强提醒和快速恢复 journey;nightly 运行完整恢复矩阵。
  • ESP-IDF / Unity:PR 构建 ESP-IDF 6.0.2 / ESP32-S3 默认固件、Timing Unity 和 esp32s3-storage-dev;构建成功不等于实板运行通过。
  • HIL / 发布验收:按实际执行的 Profile、设备、journey 和 TTS provider 记录设备、刷写、串口 readiness、资源、恢复和 cleanup 证据;HIL 不是普通 PR required check。

CI 项目

文档单列 CI 章节,说明以下项目的执行内容和结论边界:

  • workflow-lint
  • format
  • im-gateway-tests
  • coverage
  • host-tests
  • esp-idf-build
  • dependency-review
  • codeql

同时区分 PR required checks 与 IM Recovery Nightly、HIL Manual 等非 PR 工作流。CI 失败或未运行时,只能记录对应失败分类或“未验证”。

覆盖率与证据规则

  • C++ 和 IM Gateway 的 Codecov project/patch 目标均为 80%;文档明确统计分母、排除目录以及“门槛不是当前实测百分比”。
  • Python、双端契约、Host E2E、ESP-IDF/Unity 和 HIL 使用测试矩阵、journey、Profile 和 evidence 评价,不强行换算源码百分比。
  • E2E/HIL 结论记录 layer、版本、Profile、journey、阶段、断言、cleanup、失败分类和 evidence 位置。
  • 公开 artifact 只保留脱敏 JSON 和聚合信息,禁止凭据、Wi-Fi、设备/用户 ID、JWT、原始语音和完整串口日志。

验收标准

  • 新增 docs/engineering/repository-quality.md,按单元、集成、Gateway、Python、契约、E2E、ESP-IDF/Unity、HIL 分模块说明测试结论。
  • CI 测试与门禁项目单列一章,并区分 PR required check、nightly 和 HIL。
  • 文档中的测试数量、命令、路径、覆盖率配置和 workflow 名称已与仓库现状核对。
  • 明确 Host/Mock、CI、实板、真实语音和外部渠道之间不能互相替代。
  • 提供本地测试入口、覆盖率命令、E2E evidence 校验命令和相关文档链接。
  • 未改变产品行为或降低既有质量门禁。

范围

本 Issue 只维护仓库质量测试结论和验证规则文档,不改变产品代码、测试逻辑、CI 门槛或 HIL 执行策略。

Activity

  1. jing-gou commented on Aug 28, 2026

    @jing-gou
    CollaboratorAuthor

    VoiceLife 测试质量文档

    1. 当前结论摘要

    模块 当前可核对的事实 已经覆盖的边界 尚未覆盖或不能推出的结论
    C++ Host unit tests/host 注册 94 个 CTest;本次运行 90 个 unit 全部通过 Domain、Application、协议解析、IM、MCP、定时任务、存储适配器、音频/显示/板级契约 不证明 ESP-IDF 运行时、真实串口、网络、Codec、掉电和声学效果
    C++ Host integration 4 个 integration CTest,本次全部通过:runtime_smoke_test、sqlite_schedule_repository_test、voicelife_schema_test、sqlite_schedule_rule_repository_test Host 进程装配、SQLite schema/持久化和跨组件协作 不证明 PostgreSQL、真实 Gateway、设备启动时序和跨网络恢复
    IM Gateway TypeScript services/im-gateway/test/ 有 33 个 *.test.mjs,另有 test/run-tests.mjs contract runner;CI 运行 pnpm run ci Application、HTTP/SSE、持久化契约、渠道适配器、投递/outbox、配对、动作 UI、安全边界 本地覆盖率不能替代 CI;不证明真实微信/企业微信账号、生产凭据或真实设备
    Python 工具与 E2E 基础设施 18 个 tests/python/test_*.py 模块;本次 unittest discover 为 198 个用例,1 个跳过,整体通过 Profile/固件脚本、设备配置、E2E runner/evidence、契约检查、SQLite probe 没有统一源码百分比;测试工具通过不等于一次真实 E2E 通过
    双端契约 check_contract_dual_end.py 检查共享 fixture 同时被 C++ 与 TypeScript 引用 版本化 fixture 的双端引用和静态完整性 是静态引用覆盖,不是运行时路径或业务场景覆盖率
    Host E2E PR CI 运行强提醒和快速恢复两个 Host journey;nightly 运行完整恢复矩阵 真实 Gateway HTTP/SSE、跨进程状态、幂等/重放、阶段断言、失败分类和 cleanup 不包含真实 ESP32、串口、声学链路或生产渠道
    ESP-IDF / Unity PR 构建默认固件、Timing Unity 和 esp32s3-storage-dev,固定 ESP-IDF 6.0.2 / ESP32-S3 Kconfig、组件链接、目标平台可编译性和板级测试固件产物 构建成功不等于固件已在板上运行;Host gcov 不覆盖 ESP-only 代码
    HIL / 发布验收 HIL Manual 手动运行 sparkbot/pcb Profile 和 im-pairing/voice/schedule-voice/schedule-reminder/schedule-im journey 设备租约、刷写、复位、串口 readiness、真实配置、资源指标和 cleanup 只对实际执行并有脱敏 evidence 的矩阵项负责;不是普通 PR required check

    2. 分模块测试说明

    2.1 C++ Host:单元测试

    入口是 ./scripts/run_host_tests.sh,构建 tests/host/CMakeLists.txt 并执行 CTest。94 个目标中 90 个带 unit 标签;测试按 schedule、timing、im、mcp、storage、voice、display、board 和 runtime 等标签组织,可以用 ctest --test-dir build-host -L <label> 或 -R <name> 缩小范围。

    本次基线运行结果为 94/94 通过。覆盖重点是确定性规则和失败分支:日程 CRUD/递归/提醒、定时任务状态迁移、IM 契约与 SSE、MCP 输入校验和恢复、SQLite 映射、音频帧队列、串口帧路由、SparkBot/SSD1306 资产与渲染契约。

    这层使用 Host fake/in-memory 依赖。它能证明模块行为和接口契约,不能证明 FreeRTOS 调度、I2S/麦克风、真实网络、外部语音服务、串口电气质量、掉电恢复或用户听感。

    2.2 C++ Host:集成测试

    带 integration 标签的目标目前有 4 个:runtime_smoke_test 验证 Host 运行时装配,3 个 SQLite 测试验证 repository、schema 和 schedule rule 的组合行为。本次 4 个目标全部通过。

    这里的“集成”仍然是单进程 Host 集成,不包含 Gateway 进程、PostgreSQL、真实 ESP-IDF 任务或跨机器通信。需要这些边界时,应转到 Host E2E、ESP-IDF 构建或 HIL,并在结论中标注对应层级。

    2.3 IM Gateway:TypeScript 单元与组件测试

    pnpm --dir services/im-gateway run ci 依次执行格式、Lint、TypeScript、公共 API 文档检查和 pnpm run test。测试由两部分组成:

    • 33 个 test/*.test.mjs Node test 文件,覆盖 application、HTTP/SSE、PostgreSQL/in-memory persistence、渠道适配器、delivery/outbox、pairing、action UI 和生产安全边界;
    • test/run-tests.mjs,读取 contracts/im-gateway/v1/fixtures,执行双端契约、正常/非法 payload、幂等和恢复场景。

    覆盖率命令使用 c8 的 --all,只把 dist/**/*.js(排除声明文件和 scripts)纳入 Gateway 分母。Codecov project 和 patch 目标均为 80%,阈值为 0%;80% 是合并门槛,不是本文对某次运行实测百分比的声明。

    Gateway 测试使用 mock channel、in-memory 或 CI PostgreSQL 16。通过不等于已经连接真实微信/企业微信、生产数据库、生产凭据或真实设备。

    2.4 Python:工具、契约和 E2E 基础设施

    入口是 python3 -m unittest discover -s tests/python -p "test_*.py"。当前有 18 个模块,覆盖:

    • 固件构建/manifest、Profile、SparkBot 资源和设备配置;
    • E2E runner、HIL adapter、证据生成/脱敏/校验和 summary;
    • 双端契约引用、SQLite board probe、IM 配置隔离和配对启动脚本。

    本次运行结果为 Ran 198 tests、OK、skipped=1。Python 没有统一 Codecov 百分比门槛;应按测试用例、失败分类、fixture 和 evidence 判断覆盖,不能用通过数量换算源码覆盖率。

    2.5 双端契约测试

    共享 fixture 位于 contracts/im-gateway/v1/fixtures/。C++ Host 契约测试和 Gateway contract runner 分别解析这些 fixture;scripts/check_contract_dual_end.py 再检查每个有版本的 fixture 是否被两端引用。

    该检查能防止只更新一端 schema,但它是静态引用检查。它不能证明所有 fixture 已在运行时执行,也不能证明真实渠道会按同样方式传输数据。

    2.6 Host E2E 与恢复矩阵

    PR CI 通过 scripts/run_e2e.py --layer host 运行:

    • im-gateway-strong-reminder:Gateway HTTP/SSE、强提醒、阶段断言和脱敏 evidence;
    • im-gateway-recovery 的 quick 套件:快速恢复和失败分类,禁止自动重试。

    .github/workflows/im-recovery-nightly.yml 另外按日程运行完整 recovery matrix。E2E 结论必须带 layer、journey、Profile、阶段、断言、cleanup 和失败分类;没有这些 evidence,只能写“未验证”。

    2.7 ESP-IDF、Unity 与板级验证

    PR 的 esp-idf-build 使用 ESP-IDF 6.0.2 / ESP32-S3 构建默认固件、tests/board/timing_esp_unity 和 esp32s3-storage-dev。这验证目标平台的编译、Kconfig、组件链接和测试固件产物;它不是实板执行。

    板级 Unity、SQLite/FATFS probe 以及串口、复位和 readiness 需要在设备上运行,并记录固件 SHA-256、工具链版本和日志证据。目标平台代码被 codecov.yml 排除时,不能据此推断“没有测试”。

    2.8 HIL、真实语音与发布验收

    HIL Manual 只允许在受控 self-hosted Runner 上手动触发,Profile 为 sparkbot/pcb,journey 为 im-pairing/voice/schedule-voice/schedule-reminder/schedule-im。它要求设备描述符、单设备租约、ESP-IDF 工具链、真实 Gateway 配置和脱敏 evidence;失败不自动重试。

    HIL 通过只对实际执行的 Profile、设备、journey 和 TTS provider 生效。没有设备、凭据、外部服务或连续 evidence 时,必须保留 configuration、infrastructure、device 或 external 失败分类,不能写成产品通过。发布验收还要单独验证升级、回退、持久化兼容性、资源指标和人工体验。

    3. CI 测试与门禁

    CI 项目是自动化执行记录,不等同于测试模块本身。PR 的 required checks 由 .github/workflows/ci.yml 定义;安全扫描由 .github/workflows/security.yml 定义;夜间恢复和 HIL 不属于普通 PR required check。

    CI 项目 执行内容 合并/结论含义
    workflow-lint actionlint 检查全部 workflow 工作流语法和表达式正确
    format clang-format 18、Ruff 格式和静态规则 C/C++、Python 格式及 Python 静态检查通过
    im-gateway-tests Node 24、冻结 pnpm、Gateway ci、强提醒 Host E2E、快速恢复 E2E Gateway 单测/组件测试和两条 Host journey 通过;上传脱敏 evidence
    coverage C++ gcovr、Gateway c8、Codecov 上传 两端报告生成且上传成功;project/patch 目标为 80%
    host-tests 提交描述、run_checks.sh、94 个 Host CTest、架构/Profile/Python 检查、源码规模 主机行为、契约、配置和规模门禁通过
    esp-idf-build ESP-IDF 6.0.2 / ESP32-S3 默认固件、Timing Unity、esp32s3-storage-dev 构建 目标平台可编译;不代表实板运行通过
    dependency-review 依赖漏洞和许可证审查(Dependency Graph 已启用时) 发现违规时失败;能力未启用时仅记录 warning
    codeql C++、Python、TypeScript 安全扫描 扫描无阻断性安全结果

    夜间工作流另行执行:IM Recovery Nightly 运行完整恢复矩阵;HIL Manual 在受控 Runner 上按 Profile/journey 运行真实设备流程。它们的结果必须以 artifact/evidence 为准,不能用“工作流已触发”当作通过。

    CI 失败时,结论应保留失败 job、失败阶段和失败分类。没有运行的 job 只能写“未验证”,不能写成“通过”。

    4. 覆盖率与门禁

    • C++ 覆盖率由 GCC/gcovr 生成,Codecov project/patch 目标为 80%;分母按 codecov.yml 过滤,排除 tests、第三方、main、部分 ESP-only 和仍依赖实板验证的语音/音频适配器。
    • Gateway 覆盖率由 c8 生成,Codecov project/patch 目标为 80%;patch 范围为 services/im-gateway/src/**,不包含 tests、声明文件和 scripts。
    • Python、双端契约、Host E2E、ESP-IDF/Unity 和 HIL 没有统一源码百分比门槛,使用测试矩阵和 evidence 评价。
    • 覆盖率报告上传失败会使 CI 失败;Codecov 页面上的实际百分比才是某次提交的实测值。排除目录只改变统计分母,不构成测试豁免。
  2. changed the title [-][Docs] 增加仓库质量文档[/-] [+][Docs] 仓库质量文档[/+] on Aug 28, 2026
  3. pinned this issue on Aug 28, 2026
  4. added and removed
    已完成任务或功能已完成
    on Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Documented文档状态-功能用户文档已提供Proposal-Accepted决策结果-提案定稿

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions