☰
test-guard - SKILL
2026/10/1 2:42:40 网站建设 项目流程

name: “test-guard”
description: “Review generated or changed test code against universal testing rules before it ships or is presented for approval.”
risk: “critical”
source: “community”
source_repo: “amElnagdy/guard-skills”
source_type: “community”
date_added: 2026-07-13
author: “community”
tags: []
tools: []

Test Guard(测试守卫)

你正在测试代码发布之前审查生成或更改的测试代码。在第一次编写测试之后、测试被展示、提交或合并之前执行以下规则。做一个敏锐的审查者,而不是吹毛求疵的人:标记浪费维护精力或隐藏真实 bug 的问题,忽略纯粹的审美偏好。

这些规则之所以存在,是因为编码智能体会过度生成测试。常见的失败模式:断言实现细节的 mock 密集型单元测试、除一个值不同外几乎重复的测试主体,以及重新验证框架而非项目逻辑的测试。每一个在 diff 中看起来都很有成效,但会永远消耗维护成本。

何时使用

在发布之前审查生成或更改的测试代码时使用此技能。在智能体编写、编辑、生成或重构测试之后被动激活它——任何框架中的单元测试、集成测试、端到端测试或快照测试。

此技能何时激活

  • 编码智能体刚刚编写了新的测试函数或测试文件,使用任何语言
  • 你正在编辑现有测试
  • 你正在审查包含测试更改的 diff
  • 用户要求你编写、添加或审查测试

先适应项目

这些规则是通用的,但它们的应用不是。在审查之前:

  1. 检查项目自身的智能体指令(CLAUDE.md、AGENTS.md)和测试文档。项目特定的测试规则与本技能冲突时优先。
  2. 识别测试技术栈,然后阅读匹配的参考以获取具体模式:
    • Python / pytest → references/pytest.md
    • PHP / PHPUnit / Pest / WordPress → references/phpunit.md
    • JavaScript / TypeScript / Jest / Vitest → references/jest.md
  3. 如果项目调用 LLM API、使用智能体框架,或接入可观测性/遥测,还要阅读 references/llm-app-testing.md——它为 LLM 应用增加了三条规则。
  4. 映射项目的系统边界:网络调用、数据库、文件系统、时钟和随机性、第三方 SDK、LLM API。现有的夹具和测试辅助函数通常会揭示项目已经在哪里划定了这些界限。

要做什么

  1. 阅读测试代码:diff、新文件或被修改的部分。
  2. 根据下面的规则检查每个测试。
  3. 简明地报告违规:规则编号、位置、违反原因、建议修复。
  4. 如果用户在编写测试之前显式调用此技能,请在编写时应用规则——不要先写出违规再标记它们。

编写新测试时,对每个测试问:"这个测试捕获了套件中其他测试都没有捕获的什么具体 bug?"如果你不能清楚地回答,就不要写它。

九条规则

规则 1:测试行为,而非实现

从调用者的角度测试代码做什么。断言返回值和可观察的副作用。绝不断言内部辅助函数被以特定参数调用——这样的测试在每次重构时都会破坏,却捕捉不到任何东西。

违规模式:断言内部函数的 mock 被调用,而该函数不是系统边界。
修复:断言调用者观察到的返回值或状态更改。

规则 2:每个 mock 都必须有理由

只在系统边界进行 mock:网络和 HTTP 调用、LLM API、数据库、外部文件上的文件系统 I/O、时钟和随机性、第三方 SDK。绝不 mock 内部类或辅助函数来隔离一个"单元"——你制造的接缝会隐藏值得捕捉的集成 bug。

当你 mock 一个边界时,断言调用者对响应做了什么,而不是 mock 收到了特定参数。

规则 3:每个测试一个场景,变体用数据驱动

如果两个或更多测试共享相同的设置且仅输入/输出值不同,将它们合并为一个数据驱动测试(@pytest.mark.parametrize、PHPUnit#[DataProvider]、Jesttest.each)。

单独测试正确的情况:不同的设置、不同的断言、不同的 mock 配置,或恰好执行同一函数但真正不同的场景。

规则 4:每个测试都必须证明其存在的理由

问:"这个测试捕获了其他测试都没有捕获的什么 bug?"删除只捕捉打字错误、验证数据类的默认值或测试琐碎的直通逻辑的测试。

常见的无理由测试:构造函数设置属性、拒绝类型系统已经禁止的输入的函数、日志消息的字符串格式化、等于其字面值的常量。

规则 5:以场景命名测试

模式:test_<场景>_<预期结果>。名称应该读起来像需求,而不是回显函数签名。

差好
test_parse_response_missing_fieldtest_malformed_response_falls_back_to_default
test_get_language_no_classtest_element_without_class_returns_empty_language
test_add_tags_single_stringtest_single_tag_normalizes_to_list

规则 6:生产回归测试是神圣的

复现真实生产 bug 的测试总是有理由的。在名称或注释中引用事件(日期、问题 ID 或简短描述),并且绝不删除它们。它们豁免于规则 4——它们的理由是事件本身。

规则 7:不为框架保证写测试

不要测试验证库会验证、ORM 会提交、路由器返回 404,或测试框架的夹具能工作。测试你的逻辑,即位于框架之上的部分。

违规模式:一个测试在你删除项目所有自定义代码、只保留框架默认值的情况下仍然通过。

规则 8:状态和值对象是真实的,绝不 mock

绝不 mock 数据模型、DTO、实体或状态对象。构造一个真实的实例。Mock 状态会隐藏字段名拼写错误和验证错误——这正是值得捕捉的 bug。如果构造真实对象很痛苦,那是设计反馈,而不是 mock 的理由;添加一个小的构建器或工厂辅助函数。

规则 9:被测试的基础设施使用真实基础设施

当数据库查询、模式行为或持久化逻辑是测试的主题时,针对带有通过夹具应用的真实迁移的真实测试数据库运行。在那里 mock 会话什么都测不到。当持久化只是被测行为的副作用时,mock 数据库是可以的。

报告格式

标记违规时,使用此格式:

**Rule N violation** in `tests/path/file.ext::<test_name>` - What: <one sentence describing the violation> - Fix: <one sentence describing what to do instead>

按文件分组违规。如果文件没有违规,不要提及它。

严重程度指南

并非所有违规都同等重要。使用判断:

  • 必须修复:规则 1、2、8——这些隐藏真实 bug 或使测试脆弱
  • 应该修复:规则 3、4、5、7——这些导致臃肿和维护负担
  • 神圣:规则 6——绝不删除,始终允许
  • 值得注意:规则 9——测试架构;标记它,但不要因为小改动而阻塞

参考

  • references/pytest.md — Python/pytest 模式:参数化、夹具、mock 边界、真实 Pydantic 实例
  • references/phpunit.md — PHP/PHPUnit/Pest 模式,包括 WordPress 和 WooCommerce 测试边界
  • references/jest.md — Jest/Vitest 模式:test.each、模块 mock、msw、快照纪律
  • references/llm-app-testing.md — LLM 应用的三条额外规则:提示词契约、可观测性接入、智能体流程转换

此技能不做什么

  • 它不运行测试。那要用项目的测试运行器。
  • 它不执行代码风格——那是代码检查器的职责。
  • 它不决定测试什么——只决定如何测试。
  • 除非被要求审计,否则它不标记你未触及的文件中已存在的违规。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询