研发协作
生成或修改测试代码后、提交/合并前…
适用于编码代理刚写好或改完测试、或需要审查含测试改动的 diff 时,按九条通用规则把关测试质量。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
生成或修改测试代码后、提交/合并前,用通通用
解决思路
- 以严格审查者而非吹毛求疵者执行:只标记浪费维护成本或隐藏真实 bug 的问题,忽略外观偏好。
- 识别常见失败模式:断言实现细节的 mock-heavy 单元测试、仅差一个值的近似重复测试、重新验证框架而不是项目逻辑的测试。
- 先检查项目自身的 agent instructions(CLAUDE.md、AGENTS.md)和测试文档;项目特定测试规则与本技能冲突时,以项目规则为准。
- 识别测试栈,然后阅读匹配参考:Python/pytest → references/pytest.md;PHP/PHPUnit/Pest/WordPress → references/phpunit.md;JavaScript/TypeScript/Jest/Vitest → references/jest.md。
- 如果项目调用 LLM APIs、使用 agent 框架,或接入 observability/telemetry,也阅读 references/llm-app-testing.md,其中增加三条针对 LLM 应用的规则。
- 映射项目系统边界:network calls、databases、filesystem、clock and randomness、third-party SDKs、LLM APIs;现有 fixtures 和 test helpers 通常能揭示项目已在哪里划线。
- 读取测试代码:diff、新文件或被修改的片段。
- 逐条对照下面的九条规则检查每个测试。
- 简洁报告违规:规则编号、位置、为什么违规、建议修复。
- 如果用户在你写测试前显式调用本技能,就在编写时应用这些规则,不要先写出违规再标记。
- 编写新测试时,对每个测试问:"What specific bug does this catch that no other test in this suite catches?";如果不能清楚回答,就不要写它。
- Rule 1:测试行为,不测试实现。从调用者视角测试代码做什么,断言返回值和可观察副作用。绝不断言内部 helper 被以特定参数调用——那种测试每次重构都会坏,却什么都抓不到。违规模式:断言内部函数的 mock 被调用,而该函数不是系统边界。修复:断言返回值或调用者可观察到的状态变化。
- Rule 2:每个 mock 都必须有理由。只在系统边界 mock:network and HTTP calls、LLM APIs、databases、filesystem I/O on external files、clock and randomness、third-party SDKs。绝不为隔离“单元”而 mock 内部类或 helper 函数。mock 边界时,断言调用者如何处理响应,而不是断言 mock 收到了特定参数。
- Rule 3:每个测试一个场景,变体用数据驱动。如果两个或多个测试共享相同 setup,只在输入/输出值上不同,就合并成一个数据驱动测试(`@pytest.mark.parametrize`、PHPUnit `#[DataProvider]`、Jest `test.each`)。当 setup 不同、断言不同、mock 配置不同,或确实是不同场景而恰好测试同一函数时,保留独立测试才是正确的。
- Rule 4:每个测试都必须证明自己存在的理由。问:"What bug does this catch that no other test catches?" 删除只抓拼写错误、验证 data classes 默认值、或测试琐碎透传逻辑的测试。常见无理由测试:构造函数设置属性、函数拒绝类型系统已禁止的输入、log messages 的字符串格式化、常量等于其字面量。
- Rule 5:按场景命名测试。模式:`test_<scenario>_<expected_outcome>`。名称应读起来像需求,而不是复述函数签名。示例:`test_parse_response_missing_field` → `test_malformed_response_falls_back_to_default`;`test_get_language_no_class` → `test_element_without_class_returns_empty_language`;`test_add_tags_single_string` → `test_single_tag_normalizes_to_list`。
- Rule 6:生产回归测试是神圣的。复现真实生产 bug 的测试永远有理由。在名称或注释中引用事件(日期、issue ID 或简短描述),并且永不删除。它们豁免 Rule 4——其理由就是该事件。
- Rule 7:不要测试框架保证。不要测试 validation library 会验证、ORM 会提交、router 返回 404,或测试框架 fixtures 正常工作。测试的是你在框架之上写的逻辑。违规模式:删掉项目全部自定义代码、只保留框架默认值后,该测试仍然会通过。
- Rule 8:状态和值对象是真实的,永不 mock。绝不要 mock data model、DTO、entity 或 state object,而应构造真实实例。mock 状态会隐藏字段名拼写错误和验证错误——正是值得抓的 bug。如果构造真实对象很痛苦,那是设计反馈,不是 mock 的理由;添加一个小 builder 或 factory helper。
- Rule 9:被测基础设施使用真实基础设施。当 database queries、schema behavior 或 persistence logic 是测试主题时,通过 fixtures 应用真实 migrations,并针对真实 test database 运行。在那里 mock session 什么都测不到。当 persistence 只是被测行为的副作用时,mock database 是可以的。
- 报告违规时使用格式:**Rule N violation** in `tests/path/file.ext::<test_name>`;- What: <一句话描述违规>;- Fix: <一句话描述应改为怎么做>。按文件分组;文件没有违规就不要提它。
- 按严重级别处理:Must fix 为 Rules 1、2、8(隐藏真实 bug 或使测试脆弱);Should fix 为 Rules 3、4、5、7(导致膨胀和维护负担);Sacred 为 Rule 6(永不删除,始终允许);Worth noting 为 Rule 9(测试架构;标记它,但不要因小改动阻塞)。
适用边界 · 注意事项
- 不用于生产或实现代码审查(那用 clean-code-guard)。
- 不用于 CI 或 test-runner 配置、运行或调试测试、通用架构讨论。
- 不运行测试、不强制代码风格、不决定要测什么;除非被要求审计,否则不标记你未触碰文件中的既有违规。