测试策略与内部验证
测试策略与内部验证
学习目标
本章要解决什么问题:理解 ECC 如何对 246 个技能、76 个命令、40+ 钩子等纯 Markdown/JSON 内容实现 997+ 内部测试保障。
读完本章后,你将了解:
- 纯 Markdown 内容的测试策略
- 目录镜像结构与命名约定
- 目录计数 CI 强制
- 安装 Manifest 验证
前置知识
本章无外部依赖知识,建议先了解 ECC 的组件分类:
- 技能生命周期与分类管理 — 四类技能
项目实践
测试对象:不是代码,是内容
ECC 的主要资产是 Markdown 文件(技能、代理、命令、规则)和 JSON 配置(钩子、Manifest)。这些内容的”测试”不是运行逻辑,而是验证结构完整性:
测试目录结构
ECC 的 tests/ 目录镜像 scripts/ 的结构:
tests/├── lib/ # scripts/lib/ 的镜像│ ├── utils.test.js│ ├── package-manager.test.js│ ├── install/ # 安装管道测试│ └── skill-evolution/ # 技能演进测试├── hooks/ # 钩子集成测试│ └── hooks.test.js└── run-all.js # 测试入口运行方式:
# 运行所有测试node tests/run-all.js
# 运行单个测试node tests/lib/utils.test.jsnode tests/hooks/hooks.test.js测试类型
1. 文件存在性测试:
// 伪代码:验证每个技能目录都有 SKILL.mdfor (const skillDir of readdirSync('skills/')) { assert(exists(path.join('skills/', skillDir, 'SKILL.md')))}2. Frontmatter 格式验证:
// 伪代码:验证代理定义的 frontmatterfor (const agentFile of readdirSync('agents/')) { const content = read(`agents/${agentFile}`) assert(matchesYamlFrontmatter(content)) const meta = parseFrontmatter(content) assert(meta.name, '必须有 name 字段') assert(meta.description, '必须有 description 字段') assert(meta.tools, '必须有 tools 字段') assert(meta.model, '必须有 model 字段')}3. 目录计数一致性: CHANGELOG 中声明的数量必须与目录实际文件数匹配。
4. Manifest 路径存在性:
install-modules.json 中声明的所有路径必须在仓库中存在。
5. Schema 验证: Provenance 文件、安装状态等 JSON 文件必须符合对应 Schema。
目录计数 CI 强制
ECC 的 CI 流程强制检查目录计数:
skills/ 目录数 = CHANGELOG 中声明的技能数agents/ 目录数 = CHANGELOG 中声明的代理数commands/ 文件数 = CHANGELOG 中声明的命令数如果任何一项不匹配,CI 失败。这确保了:
- 文档与代码一致性
- CHANGELOG 数字不会过时
- 新增/删除组件时必须更新 CHANGELOG
钩子集成测试
tests/hooks/hooks.test.js 测试钩子系统的集成行为:
hooks.json格式正确- 所有引用的脚本文件存在
- 异步钩子超时配置合理
- 钩子 ID 唯一
997+ 测试的来源
“997+ 内部测试”不是传统的单元测试数,而是:
- 文件存在性检查(246 个技能 × 每个多个检查项)
- Frontmatter 格式验证(61 个代理 + 76 个命令)
- Manifest 路径检查(模块 × 路径数)
- Schema 验证(Provenance、安装状态)
- 目录计数检查
- 钩子格式和引用检查
这些检查的总数超过 997。
问题与规避
测试不验证内容正确性
问题:测试只验证文件存在和格式,不验证 SKILL.md 中的指令是否正确。
ECC 的规避:
- 内容正确性通过代码审查(
code-reviewer代理)保证 - 社区 PR 流程允许用户报告无效或过时的技能
/skill-health命令运行时检查技能的可加载性
新增技能忘记更新 Manifest
问题:新增技能但未添加到 install-modules.json,导致无法安装。
规避方案:
- CI 验证
install-modules.json中的路径与skills/目录的一致性 - CONTRIBUTING.md 中要求新增技能时同时更新 Manifest
目录计数与 CHANGELOG 不一致
问题:删除技能但未更新 CHANGELOG 中的数字。
规避方案:
- CI 强制检查目录计数与 CHANGELOG 的一致性
- PR 模板提醒贡献者更新数字
设计取舍
为什么测试数如此高(997+)?
因为 ECC 的主要资产是内容文件(Markdown/JSON),每个文件都需要独立的验证:
- 每个技能需要验证:文件存在 + frontmatter 格式 + 非空 + Manifest 路径 = 4+ 个检查
- 246 个技能 × 4 检查 = ~1000 个检查点
这不是过度测试:纯内容项目的测试策略与代码项目不同。内容的”bug”通常是结构性的(文件缺失、格式错误),而非逻辑性的。
为什么不用 Jest/Vitest?
ECC 使用 Node.js 原生 assert 模块:
- 优势:零依赖,
node tests/run-all.js即可运行 - 代价:没有丰富的断言库和报告格式
- 为什么:ECC 是 CommonJS 项目,不引入额外的测试框架依赖
参考来源
- 源码验证:
tests/目录 — 测试套件 - 源码验证:
tests/run-all.js— 测试入口 - 源码验证:
scripts/ci/validate-skills.js— CI 技能验证 - 源码验证:
scripts/ci/validate-install-manifests.js— CI Manifest 验证 - 源码验证:
package.json—test命令定义