样例:测试规范
公开教程 · 无需登录

样例:测试规范

下面是 CampusClaw 项目《测试规范 · CampusClaw》的原文,逐条列出,可直接照抄。

适用:backend/**/*_test.go、apitest/
被谁读到:规则文件 .cursor/rules/testing.mdc,globs **/*_test.go;技能「按规范补测试」

1. 层次与位置

层次放哪里覆盖什么
单元被测包内 *_test.go业务规则:命中阈值、切分规则、作业状态流转
接口apitest/cases/<URL 路径>/<方法>.json每条能力的正常路径与失败路径
端到端apitest/cases/ 中标 e2e 的目录只覆盖主路径:登录 → 检索 → 提问 → 看到出处

接口测试目录与 URL 对齐,文件名就是方法。例如 apitest/cases/api/v1/materials/GET.json。

2. 用例来源:每个测试说得出在判哪一条规约

测试名或注释里写清规约编号,例如:

materials_cross_class - R3.1 跨班与不存在返回一致的 404
submission_twice      - R5.2 同一幂等键重复提交返回首次结果

说不出在判哪一条的测试,通常是顺手写的形状检查,删掉比留着好。

3. 三类组织(含边界)

每条能力按正常路径 / 失败路径 / 边界归组:

  • 正常路径:本班检索命中并返回出处;
  • 失败路径:跨班访问、未登录、依赖不可达(向量库停掉时 mode=hybrid 返回 503);
  • 边界:空资料库、SEARCH_VECTOR_MIN 边界值附近、page_size 取到上限。

边界用等价类划分的两端,不用随机值。

4. 不许只断言形状

这三句放在一起,把被测逻辑改坏它还是绿的:

assert.NoError(t, err)
assert.NotNil(t, rows)
assert.Len(t, rows, len(input))

要断言值:跨班访问的响应体与「不存在」的响应体逐字节相同;混合检索的结果里不含另一个班的标题。

判据:改坏被测逻辑,这个测试会不会红。 会红才算断言到了行为。

5. 数据隔离

  • 测试用独立的库: docker compose -f docker-compose.test.yml 起一套,或用独立的 schema。
  • 预置 A / B 两个班(含教师与学生各一名),每条用例运行前后自行清理;
  • 随机化执行顺序后结果一致;跨班级的用例不依赖执行先后。

6. 外部依赖用替身

模型与向量库在单元测试中用替身;接口测试可以打真实服务,但要在只读数据上执行。禁止依赖真实时间与真实外部网络:断网后单元测试仍应全部通过。

7. 一键运行与通过判定

make check        # go-vet go-build go-test fe-typecheck fmt-check complexity layout secret-scan ...

任一子项非零退出码即未通过。不得为了让门禁变绿而放宽其中的检查或删断言。

t.Skip 必须带理由与追踪编号;跳过用例数只许下降,不许增长。

8. 变更时的要求

每次变更至少补写与其场景对应的用例;修复缺陷先补一条能复现该缺陷的用例,再改代码,最后保留该用例。

违反时

失败即阻断。若认为某条断言本身写错了,改断言并在变更说明里写明原因,不由执行者自行跳过。