跳到主要内容

Fixtures 与测试设计

# Fixtures 与测试设计

修订记录

版本日期修订说明
v0.12026-05-01建立当前设计基线;延续 kunora-wiki 作为 llm-wiki 方案的既有产品封板和工程设计,不推倒重来。

1. 文档目标

本文定义 kunora-wiki 自研模块共享的测试夹具、契约测试和 golden tests 规则。

它的目标是让公共契约在实现前具备可验证标准:不同模块、不同实现者、不同 agent 不能各自解释路径、hash、manifest、错误码、状态流转和 API 响应结构。

本文不创建具体测试代码,也不规定测试框架。测试框架属于实现阶段选择;fixture 结构、覆盖范围和验收语义属于 common 契约,必须先稳定。

2. 设计目标

  • 用 fixture 固化跨模块输入输出,避免实现阶段字段漂移。
  • 用 contract test 验证 producer 和 consumer 对同一契约的理解一致。
  • 用 golden test 验证路径、hash、id、manifest、错误对象等稳定输出不会被无意改动。
  • 用 negative fixture 固化拒绝条件,确保非法输入不会进入正式内容、索引或 agent 写入链路。
  • 用模块准入矩阵约束每个自研模块在进入实现前必须覆盖的公共测试类型。

3. 非目标

  • 不规定单元测试框架、mock 框架、CI 平台或测试运行命令。
  • 不覆盖 GitHub、Docusaurus、RAGFlow、Meilisearch 的常规部署可用性测试。
  • 不把外部产品的私有返回结构作为 golden 输出。
  • 不用 snapshot 代替契约定义;snapshot 只能验证已定义契约。
  • 不要求 MVP 阶段一次性覆盖性能、压力和混沌测试。

4. Fixture 目录结构

后续实现阶段建议在仓库根目录创建 fixtures/common/**,用于保存公共契约样例。目录规划如下:

fixtures/
common/
path/
hash/
id/
config/
workspace/
sync/
review/
manifest/
index/
answer/
access/
agent/
error/
目录覆盖内容主要消费者
path/路径规范化、非法路径、URL/anchor 生成WorkspaceStore、Display Adapter、Index Adapter、Answer API
hash/Markdown 规范化、contentHash、hash 格式WorkspaceStore、SyncEngine、Index Adapter
id/documentIdchunkIdrunIddedupeKeyidempotencyKey全部自研模块
config/source、publish、index、agent access 配置ConfigManager、SyncEngine、Index Adapter、Agent Access API
workspace/DocumentRecord、文件状态、manifest 输入WorkspaceStore、Display Adapter、Index Adapter
sync/SyncChangeSourceChanges、冲突和删除SyncEngine、ReviewBridge
review/review report、check report、PR payload 标准结构ReviewBridge、Agent Access API、AgentBridge
manifest/page、publish、site、index manifestDisplay Adapter、Index Adapter、Answer API
index/IndexDocumentSearchResult、部分失败Index Adapter、Answer API
answer/AnswerRequestAnswerResult、citation、无答案Answer API、Agent Access API
access/tool request、scope、policy 拒绝、幂等反馈Agent Access API、AgentBridge
agent/iteration task、RAGFlow 输出、agent reportAgentBridge、ReviewBridge
error/ErrorObject、状态传播、retryable 标记全部自研模块

5. Fixture 命名规则

Fixture 文件名必须表达场景和预期结果,不使用 test1samplemock 这类不可审查命名。

类型命名规则示例
正常输入<domain>.<scenario>.valid.<ext>source.single.valid.yaml
非法输入<domain>.<reason>.invalid.<ext>path.absolute.invalid.json
预期输出<domain>.<scenario>.expected.<ext>hash.markdown-lf.expected.json
golden 输出<domain>.<scenario>.golden.<ext>manifest.publish-basic.golden.json
回归用例<domain>.<issue-or-case>.regression.<ext>sync.case-conflict-delete.regression.json

Fixture 内容必须满足:

  • 每个 fixture 顶层包含 fixtureVersioncaseIddescriptioninputexpected
  • caseIdfixtures/common 下唯一。
  • 预期失败 fixture 必须写明 expected.error.codeexpected.error.retryable
  • 涉及时间的 fixture 必须使用固定时间,不使用当前时间。
  • 涉及随机 id 的 fixture 必须使用固定 seed 或显式 expected id。
  • 涉及外部产品的 fixture 只能保存 adapter 标准结构,不能保存供应商私有完整响应。

6. Contract Test 类型

Contract test 验证模块间契约,不验证模块内部实现细节。

测试类型目的必须验证
Schema contract对象字段、必填项、枚举、类型和版本缺字段拒绝、未知字段策略、版本兼容
Producer contractproducer 输出是否满足公共结构输出字段、状态、错误对象、幂等 key
Consumer contractconsumer 是否只依赖公共字段不读取私有字段、不假设外部产品结构
Adapter contract外部产品响应是否被转换为标准结构错误映射、重试标记、降级输出
Persistence contract写入 Git 或状态文件的结构是否稳定canonical JSON、manifest 字段、hash/id 稳定性
Idempotency contract重试是否不会产生重复副作用相同 key 返回同一结果或安全 no-op

Contract test 必须优先覆盖 Public Contract,其次覆盖跨两个以上模块共享的 Internal Contract。

7. Golden Test 类型

Golden test 用于稳定确定性输出。任何 golden 更新都必须被当作契约变更审查,不能在失败后无解释刷新。

Golden 类型输入输出更新要求
Path golden原始路径、source idnormalized path、publish path、anchor需要说明路径规则变更原因
Hash goldenMarkdown 文本contentHash、canonical JSON hash需要说明规范化规则变更原因
ID goldenpath、hash、caller、task 输入document/chunk/run/dedupe/idempotency id需要说明稳定键变更影响
Manifest goldenDocumentRecord 列表page/publish/site/index manifest需要说明下游消费影响
Error golden失败输入ErrorObject 和 propagated status需要说明调用方处理影响
Answer goldensearch result/context packanswer result、citation、no-answer需要说明用户可见行为影响

Golden test 的输出文件必须使用稳定排序、稳定缩进和稳定字段顺序,避免无意义 diff。

8. 必备 Fixture 清单

8.1 路径、hash 与 id

Fixture场景预期
fixtures/common/path/valid-publish-paths.json合法 publish path 集合全部规范化为 / 分隔相对路径
fixtures/common/path/invalid-paths.json绝对路径、..、空 segment、保留目录越界返回 path.invalid 或更具体错误
fixtures/common/hash/markdown-lf.mdLF Markdown生成稳定 contentHash
fixtures/common/hash/markdown-crlf.mdCRLF Markdown与 LF 等价内容生成相同 contentHash
fixtures/common/hash/markdown-bom.md带 BOM MarkdownBOM 不影响 contentHash
fixtures/common/id/document-id-stable.json同一路径不同内容documentId 不变,contentHash 变化
fixtures/common/id/idempotency-by-caller.json不同 caller 相同操作idempotencyKey 不同

8.2 配置与工作区

Fixture场景预期
fixtures/common/config/sources.single.valid.yaml单 source 配置生成 SourceConfigConfigBundle
fixtures/common/config/sources.duplicate-publish-path.invalid.yaml两个 source 写入同一 publish path返回 config.duplicate_path
fixtures/common/config/index.disabled.valid.yaml索引关闭Index Adapter 不执行 upsert
fixtures/common/workspace/document-record.valid.json正常文档记录hash、path、status 完整
fixtures/common/workspace/document-record-missing-hash.invalid.json缺少 contentHashschema contract 拒绝

8.3 同步、审核与 manifest

Fixture场景预期
fixtures/common/sync/add-update-keep-conflict.json新增、更新、保持、冲突混合输出稳定 SourceChanges
fixtures/common/sync/delete-source-page.json上游删除页面输出 delete change,不直接删除正式内容
fixtures/common/review/check-report-blocking.json阻断性检查失败ReviewBridge 生成 failed check
fixtures/common/manifest/publish-manifest.valid.json基础发布 manifestcanonical JSON 稳定
fixtures/common/manifest/site-manifest-build-failed.json展示构建失败不生成 success site manifest
fixtures/common/manifest/index-manifest.partial.json部分索引失败成功项和失败项可区分

8.4 索引、问答、访问与 agent

Fixture场景预期
fixtures/common/index/upsert-delete-idempotent.json重复 upsert/delete无重复副作用
fixtures/common/index/search-result-citation.json搜索结果带引用Answer API 可生成标准 citation
fixtures/common/answer/no-answer.json检索不足或置信度不足返回 answer.no_answer,通常 HTTP 200
fixtures/common/answer/citation-path-anchor.json引用包含 path 和 anchorcitation 可回到展示页面
fixtures/common/access/forbidden-scope.jsoncaller 请求未授权 scope返回 access.forbidden,不调用下游
fixtures/common/access/feedback-dedupe.json重复反馈使用 dedupeKey 合并或安全 no-op
fixtures/common/agent/concurrent-change.jsonagent 基于过期内容生成 diff返回冲突,不覆盖正式内容
fixtures/common/agent/ragflow-invalid-output.jsonRAGFlow 输出缺字段AgentBridge 拒绝创建 PR

9. 错误与状态测试要求

错误测试必须覆盖错误对象、状态传播和降级语义。

场景输入预期
配置错误无效 source schemaconfig.invalid_schemaretryable=false
路径越界../publish/a.mdpath.traversalpath.invalid,不读写文件
Git 写入冲突base revision 过期workspace.conflict,可由人工或重试解决
展示构建失败Docusaurus build adapter 返回失败page/publish 成功状态不被错误标记为 site 成功
索引部分失败部分文档 upsert 失败index manifest 标记 partial,不回滚 Git 内容
RAGFlow 不可用answer 或 iteration 调用失败不编造答案,不创建改进 PR
权限不足caller scope 不满足 policyaccess.forbidden,不泄漏受限内容

所有错误测试必须断言:

  • code 使用 <domain>.<reason>
  • severity 与调用方处理方式一致。
  • retryable 不被默认设为 true。
  • moduleoperation 可用于审计定位。
  • details 不包含密钥、token、完整私有配置或未授权内容。

10. 模块准入矩阵

模块进入实现前,必须声明自己消费和生产哪些 fixture,并满足下表最低测试要求。

模块必须通过的 common 测试
ConfigManagerconfig schema、config invalid、config impact、error object
WorkspaceStorepath、hash、id、document record、manifest persistence、workspace conflict
SyncEngineconfig input、source changes、sync conflict、delete semantics、idempotency
ReviewBridgereview report、check report、blocking status、PR payload adapter contract
Display Adapterpage manifest、site manifest、path/anchor、build failure degradation
Index Adapterindex document、index manifest、upsert/delete idempotency、partial failure
Answer APIanswer request/result、search result、citation、no-answer、index unavailable
Agent Access APIscope、policy、tool request/result、feedback dedupe、audit event
AgentBridgeiteration task、RAGFlow output validation、concurrent change、PR report

如果模块不满足对应 common 测试,模块设计文档必须显式记录延期原因和补齐计划。

11. CI 与本地检查要求

实现阶段的 CI 至少应分三层:

层级运行时机内容
Fast contract checks每次提交或 PRschema、path/hash/id、fixture parse、基础 golden
Module contract checks模块变更 PRproducer/consumer contract、adapter mock、错误状态传播
Integration smoke checks合并前或 nightly从 source 到 manifest/index/answer 的最小链路

本地检查应支持只运行 common fixture,以便在模块实现前先验证公共契约没有被破坏。

CI 失败处理规则:

  • Contract test 失败默认阻断合并。
  • Golden test 失败必须人工确认是否为预期契约变更。
  • Negative fixture 失败必须阻断合并,因为它代表非法输入被接受。
  • 外部产品不可用导致的 adapter 测试失败,应区分 mock contract 失败与真实环境不可用。

12. 契约稳定完成标准

development/common 的 fixture 与测试契约达到稳定状态,需要满足:

  • Public Contract 都至少有一个 valid fixture 和一个 invalid fixture。
  • 跨两个以上模块共享的 Internal Contract 都至少有 schema contract。
  • 路径、hash、id、manifest 和错误对象都有 golden test。
  • 每个自研模块在自己的设计文档中引用对应 common fixture 范围。
  • Golden 输出变更有 review 说明,不允许无说明批量刷新。
  • Fixture 不包含真实密钥、真实用户隐私数据或外部产品私有完整响应。

13. 待实现事项

  • 创建 fixtures/common/** 实际目录和首批 fixture 文件。
  • 为公共数据结构建立 schema 校验。
  • 为 path/hash/id 规则建立 golden 输出。
  • 为 Public Contract 建立 producer/consumer contract test。
  • 在 CI 中增加 common fixture 检查入口。
对此页面有疑问?

问答功能将在后续接入 Answer API。当前可通过页面底部的反馈链接提交问题。

页面来源草稿
来源项目kunora-wiki
分支docs-publish
路径technology/components/kunora-wiki/development/common/06-fixtures-and-tests.md