Repository navigation
[Docs] 仓库质量文档 #385
Description
Activity
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_testHost 进程装配、SQLite schema/持久化和跨组件协作 不证明 PostgreSQL、真实 Gateway、设备启动时序和跨网络恢复 IM Gateway TypeScript services/im-gateway/test/有 33 个*.test.mjs,另有test/run-tests.mjscontract runner;CI 运行pnpm run ciApplication、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-S3Kconfig、组件链接、目标平台可编译性和板级测试固件产物 构建成功不等于固件已在板上运行;Host gcov 不覆盖 ESP-only 代码 HIL / 发布验收 HIL Manual手动运行sparkbot/pcbProfile 和im-pairing/voice/schedule-voice/schedule-reminder/schedule-imjourney设备租约、刷写、复位、串口 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.mjsNode 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-lintactionlint检查全部 workflow工作流语法和表达式正确 formatclang-format 18、Ruff 格式和静态规则 C/C++、Python 格式及 Python 静态检查通过 im-gateway-testsNode 24、冻结 pnpm、Gateway ci、强提醒 Host E2E、快速恢复 E2EGateway 单测/组件测试和两条 Host journey 通过;上传脱敏 evidence coverageC++ gcovr、Gateway c8、Codecov 上传 两端报告生成且上传成功;project/patch 目标为 80% host-tests提交描述、 run_checks.sh、94 个 Host CTest、架构/Profile/Python 检查、源码规模主机行为、契约、配置和规模门禁通过 esp-idf-buildESP-IDF 6.0.2 / ESP32-S3 默认固件、Timing Unity、 esp32s3-storage-dev构建目标平台可编译;不代表实板运行通过 dependency-review依赖漏洞和许可证审查(Dependency Graph 已启用时) 发现违规时失败;能力未启用时仅记录 warning codeqlC++、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 页面上的实际百分比才是某次提交的实测值。排除目录只改变统计分母,不构成测试豁免。
- 33 个
- pinned this issue
on Aug 28, 2026
背景
仓库的测试结论分布在 CMake、Python/Gateway 测试入口、CI workflow 和 HIL 脚本中。需要一个以“测试证明了什么、没有证明什么”为核心的质量文档,方便贡献者和 Review 者判断改动的验证范围。
目标
更新
docs/engineering/repository-quality.md,按测试模块说明当前覆盖情况,并将 CI 项目单独成章。文档不把测试数量或覆盖率门槛误写成产品行为已经全面验证。已记录的测试结论
tests/host注册 94 个 CTest,其中 90 个带unit标签;基线运行 94/94 通过。覆盖 schedule、timing、IM、MCP、storage、voice、display、board 和 runtime 等 Host 可测模块。test/*.test.mjs文件,另有test/run-tests.mjscontract runner,覆盖 application、HTTP/SSE、持久化、渠道适配器、投递/outbox、配对、action UI 和安全边界。check_contract_dual_end.py做静态引用检查;该检查不等同于运行时覆盖率。esp32s3-storage-dev;构建成功不等于实板运行通过。CI 项目
文档单列 CI 章节,说明以下项目的执行内容和结论边界:
workflow-lintformatim-gateway-testscoveragehost-testsesp-idf-builddependency-reviewcodeql同时区分 PR required checks 与
IM Recovery Nightly、HIL Manual等非 PR 工作流。CI 失败或未运行时,只能记录对应失败分类或“未验证”。覆盖率与证据规则
验收标准
docs/engineering/repository-quality.md,按单元、集成、Gateway、Python、契约、E2E、ESP-IDF/Unity、HIL 分模块说明测试结论。范围
本 Issue 只维护仓库质量测试结论和验证规则文档,不改变产品代码、测试逻辑、CI 门槛或 HIL 执行策略。