mcpField
T
test-quality-audit

test-quality-audit

github.com/marcellocurto测试与质量374 次安装2 天前更新
代码仓库

关于 test-quality-audit

用于审查测试是否保护用户或调用方依赖的行为,并能发现现实回归的技能。它引导代码审查者基于证据分类测试并简明报告发现。

主要功能

  1. 01按行为契约评估测试
  2. 02检查覆盖范围与执行条件
  3. 03将测试分类为保留、修复、删除或新增
  4. 04验证测试对现实回归的敏感性
  5. 05围绕证据组织审查发现

适用场景

  1. 01审查拉取请求中的测试变更
  2. 02评估测试能否捕获已报告的回归
  3. 03发现跳过或选择性运行测试造成的缺口

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/marcellocurto/skills --skill test-quality-audit

安装后在 Claude Code 中输入/test-quality-audit确认已加载。

详细介绍

测试质量审计

当测试能在契约出现真实回归时失败,就值得保留。这里的契约是指用户或调用方所依赖的行为。应以此标准评判每项测试。覆盖率、测试数量,以及测试是否先于代码编写,都不重要。失败时能指向真实缺陷的小型测试套件,胜过大型套件,因此不要默认要求增加测试。

只有证据表明测试并未保护任何契约,或其维护成本超过了保护价值时,才将其判定为薄弱。如果缺少上下文,无法做出判断,就应如实说明,而不是假定测试价值不大。

阅读内容

从正在审查的测试开始,然后只阅读判断测试所需的内容:

  • 被测实现及其公开行为或用户可见行为
  • 重要分支和失败路径
  • fixtures、mock、factory、快照和 helper
  • 针对相同行为的现有测试
  • 可用时,PR 意图、缺陷报告或已知回归
  • 决定测试是否运行的命令、筛选规则和前置条件
  • 外部边界:数据库、API、身份验证、队列、文件系统、时间、随机性、网络

只有在测试声称保护的行为、真实依赖、风险分支或相邻的更强覆盖仍不明确时,才继续阅读。

方法

对于每项测试或每组测试,请回答:

  1. 它声称保护什么契约?
  2. 它实际保护什么?
  3. 哪种真实回归会让它失败?这种回归是否重要?
  4. 契约是否可能被破坏,而测试仍然通过?
  5. 无害的重构是否可能导致测试失败?
  6. 它断言的是调用方所依赖的结果,还是仅仅确认变更产物存在,例如文件、键、选项、调用或代码行?只固定差异的测试不保护任何契约;当修复后的行为再次出错时会失败的回归测试则能保护契约。
  7. 它处于恰当的测试层级吗:单元、集成、契约、端到端,还是都不是?
  8. 所声称的验证是否确实在相关条件下运行了该测试?
变更的测试

比较变更前后测试所保护的内容:旧测试能捕获、而新测试却能接受的真实回归是什么?应结合阅读变更过的断言、fixtures、mock、快照、跳过项和配置。只有在契约经决策发生变化,或已证明旧测试有误时,才可以接受保护范围的丢失。仅仅接口发生变化,并不足以成为删除其失败用例的理由。

当某项行为被移除时,随之删除的测试不算保护范围丢失。请检查剩余测试套件是否仍覆盖依赖于被移除部分的内容。

检查敏感性

如果无法确定某项重要测试是否会因其声称能捕获的回归而失败,请使用已有的“修复前失败”证据,或在已知存在缺陷的版本上运行测试。如果引入临时缺陷可以解决疑问,请在一次性副本中进行,保持测试不变,还原副本,并报告观察结果。不要修改正在审查的检出版本,也不要要求配备变异测试基础设施。测试在某个缺陷版本上通过,只能证明它无法捕获该缺陷。

分类

  • 保留:保护契约,并会在真实回归时失败。
  • 修复:意图有价值,但执行薄弱。应围绕可观察行为或风险边界重写。
  • 删除:不保护任何契约,或其维护成本超过保护价值,且没有值得重写的意图。包括冗余、同义反复和仅关注覆盖率的测试,以及不承载任何兼容性承诺的静态内容、文案、导航结构或非关键配置测试。
  • 新增:某项契约尚未经过测试,且真实回归有可能发生。对于移除内容、设计探索、原型、静态内容、文案或配置,不要建议新增测试;但如果配置承载了调用方所依赖的兼容性承诺,则例外。

需要调查的模式

列表中的模式是值得进一步检查的理由。在建议更改之前,应明确其契约、测试能捕获或遗漏的回归,以及具体的维护成本。能够为契约提供有用证据的模式应予以保留。

  • 缺失断言。 测试某项功能、路由、选项、菜单项或默认设置已不复存在,并不能保护任何契约,应予以删除;但如果缺失本身就是承诺,则例外,例如未经身份验证无法访问某个端点,或默认关闭破坏性操作。
  • 调用、次数和顺序断言。 当交互本身就是契约时,应予以保留,例如重复提交时恰好发送一条消息,或遵循规定的协议顺序。如果这类断言锁定了私有辅助函数的调用方式,而承诺的结果仍可能失败,则应删除或修正。
  • 常量和测试夹具。 保留对已发布格式、协议值和兼容性要求的检查。删除将由测试夹具控制的值与自身比较,或重复检查非关键配置的断言。包装器或 getter 可能包含值得测试的行为,应根据其行为进行判断。
  • 快照。 如果快照保护的是稳定且有意义的输出,并且变更会经过语义审查,则应予以保留。应调查噪声较多的附带输出、无人注意到的契约变更,以及接受回归的大批量快照更新。使用快照本身并不构成缺陷。
  • 模拟对象及其他替身。 如果它们能隔离契约或控制故障条件,则应予以保留。如果它们替代了被测行为,或掩盖了测试声称要验证的集成、持久化或转换环节故障,则应标记出来。
  • 测试设置和能力选择。 如果测试夹具初始化状态、启用功能或提供受支持工作流并不保证的配置,则应标记出来。对有效准备状态的测试可以保留,但它们不能证明系统已就绪或具备相应能力。测试套件可能充分测试了错误处理,却没有测试成功路径,或成功路径已损坏。
  • 执行缺口。 检查选择性启用项、跳过项、预期失败标记和所需基础设施。验证命令不会运行的测试套件,无法支撑成功声明。建议在必需的命令中运行必需且确定的测试;如果缺少前置条件,应明确失败;可选的实时服务检查则应明确标示。
  • 计算得出的预期值。 检查预期值是否独立于实现而得出。重复实现中的计算方式会掩盖其中的缺陷。如果计算结果源自契约,则使用计算得出的预期值没有问题。
  • 重叠测试或内部测试。 在认定测试冗余或受实现细节限制之前,应比较它们检查的内容。能捕获其他测试遗漏的重要故障的内部测试应予以保留。如果无害的重构会导致断言失败,或实际回归仍能通过,则应标记对私有结构的断言。
  • 针对旧 API 的测试。 检查被替换的生产 API 或适配器是否仅因测试仍在使用而保留下来。在建议移除之前,先查找其他调用方和兼容性要求。如果不再需要旧 API,应将有用的测试归类为 Fix,并迁移到替代 API,同时检查相同行为。如果某个内部接口尚未被替代,且只有测试会直接调用它,则应将其作为 audit-code-complexity 技能中的复杂度问题;在此处,应根据其测试保护的行为来评判这些测试。
  • 故障和时序覆盖。 如果缺少故障路径、使用休眠等待或时序不受控制,可能掩盖现实缺陷或导致结果不可靠,则应标记出来。不要仅仅因为存在某个边界情况,就要求覆盖它。

输出

先给出结论。只保留能证明各项分类的证据;省略重复的测试摘要和泛泛的测试建议。

按导致保护失效或增加维护成本的机制,归类重复出现的弱点,并给出代表性示例和受影响的测试组。若契约或证据不同,请分别分类;语法相似不是合并问题的理由。

仅使用能提供信息的章节:

  • 结论:强(没有实质性缺口)、够用(存在无需立即处理的缺口)、参差不齐、测试不足、受实现约束,或大多是噪声。
  • 已覆盖的保护:测试目前覆盖的契约。
  • 最大问题:按优先级排列的问题,附示例和建议。
  • 保留 / 修复 / 删除 / 添加:具体分类。
  • 最高价值的后续改动:能提升信心的最小改动集合。

如果测试很强,请明确说明,并指出仍然存在的盲点。只有在缺少上下文导致无法判断测试保护什么时才提问。

编辑测试

只有用户明确要求时才编辑测试。编辑时,应保留保护契约的测试,围绕可观察行为重写薄弱测试,删除冗余、误导、脆弱或未保护任何契约的测试,并为重要风险添加有针对性的回归测试。如有可用的测试命令,请运行最相关的命令;否则说明下一步最合适的检查方式。

只有在需求变更或已证明原有测试有误时,才更改预期结果。调整接口或测试设置时,应保留受保护的用例。如果更正测试后暴露出生产缺陷,应让测试保持失败并报告该问题;清理测试并不授权修复生产代码或弱化预期结果。分别报告通过、失败、跳过和无法运行的结果。

约束

  • 不要因为测试已经存在就为其辩护。
  • 不要要求每一行或每个辅助函数都配备测试,也不要把单元测试等同于模拟一切。

评论

支持 Markdown