Claude Code hooks 自动运行测试,最适合解决一个常见问题:你已经在 CLAUDE.md 里写了“改完代码请运行测试”,但 Claude Code 有时会忘,有时会跑太大的测试,有时测试失败后只给你一段泛泛解释。
Hooks 的价值在于把“希望它记得”变成“事件发生时一定执行”。官方文档把 hooks 描述为在 Claude Code 生命周期特定节点自动执行的用户自定义命令,可以用来格式化代码、拦截危险操作、发送通知、注入上下文和执行验证。对测试来说,最常用的是 PostToolUse 和 Stop。
快速结论
如果只是想在 Claude Code 编辑文件后自动跑相关检查,优先用 PostToolUse,并把 matcher 限定在 Edit|Write。
如果你想在 Claude Code 准备结束一轮任务时做最终验证,适合用 Stop。但不要一上来就在 Stop 里跑全量测试,否则一次小改动也可能变成很慢、很贵、很吵的流程。
比较稳的做法是:
PostToolUse只做轻量检查,例如格式化、类型检查片段、按文件名选择测试。Stop做最终提醒或运行一个更窄的验证脚本。- 测试失败时只输出关键摘要,不要把完整日志塞回上下文。
- 项目级 hooks 放在
.claude/settings.json,具体逻辑放到.claude/hooks/脚本里。 - 先在一个小项目里试运行,再推广到团队仓库。
先想清楚:自动运行什么测试
很多人配置 hooks 的第一反应是:
|
|
这通常不是最佳起点。自动化测试越靠近 Claude Code 的编辑动作,就越应该短、准、可重复。
更好的分层是:
| 场景 | 建议命令 |
|---|---|
| 改了单个前端组件 | 相关单测、类型检查、lint |
| 改了后端函数 | 相关 package 的单测 |
| 改了配置文件 | 配置校验、构建 dry run |
| 改了 Markdown | 链接检查或 front matter 检查 |
| 准备结束任务 | 汇总运行一次最小验证 |
| 准备提交或发布 | 手动运行完整测试和构建 |
Hooks 不应该代替 CI。它更像本地安全网:及时发现明显错误,减少 Claude Code 连续在错误方向上改文件。
推荐目录结构
不要把复杂逻辑全部塞进 settings.json 的一行命令里。后面调试会很痛苦。
建议这样放:
|
|
Windows 项目也可以用 PowerShell:
|
|
文章下面先用 Bash 示例说明思路,再给 PowerShell 版本。真正落地时,按项目团队常用 shell 选择一种即可。
用 PostToolUse 在编辑后跑相关测试
PostToolUse 会在工具调用之后触发。自动测试场景里,通常只关心文件写入类工具,所以 matcher 可以限制为 Edit|Write。
.claude/settings.json 示例:
|
|
这个配置只负责注册 hook。真正判断“改了什么文件、该跑什么测试”,放到脚本里。
Bash 脚本:按文件类型选择命令
.claude/hooks/run-related-tests.sh:
|
|
然后给脚本执行权限:
|
|
这个脚本故意比较保守。它没有直接跑全量测试,也没有把日志写得很长。你可以按项目实际情况改成 pnpm test、bun test、pytest path/to/test.py、go test ./pkg/foo 等命令。
PowerShell 版本
如果团队主要在 Windows 上用 Claude Code,可以写 PowerShell 脚本。
.claude/hooks/run-related-tests.ps1:
|
|
对应的 .claude/settings.json 可以写:
|
|
注意:PowerShell 字符串、路径和引号很容易出问题。先在普通终端里手动运行脚本,再放进 hook。
测试失败后 Claude Code 会怎样
Hook 命令的输出会进入 Claude Code 的工作流。测试失败时,Claude Code 通常会看到错误输出,然后继续修复。
但这里有两个坑。
第一,失败输出不要太长。完整测试日志、快照 diff、依赖安装日志可能非常大,会把上下文撑爆。脚本里可以只保留最后几十行:
|
|
第二,测试命令要稳定。不要让 hook 依赖交互式输入、随机端口、临时网络服务或需要人工确认的命令。Hooks 适合确定性检查,不适合复杂人工流程。
用 Stop 做最终检查
PostToolUse 更适合“编辑后立即检查”。Stop 更适合“这一轮准备结束前再确认一下”。
例如你可以在 Stop 里运行一个很轻的最终检查脚本:
|
|
.claude/hooks/final-check.sh:
|
|
这个版本只是提醒,不自动跑测试。它适合刚开始启用 hooks 的团队:先让 Claude Code 在结束前看见检查清单,确认不会打扰正常工作,再逐步把某些检查自动化。
什么时候不要自动跑测试
并不是所有项目都适合一编辑就跑测试。
下面几种情况要谨慎:
- 单测很慢,每次运行超过 30 秒;
- 测试需要数据库、队列、浏览器或外部 API;
- 测试会改本地数据;
- 测试日志很大;
- 项目还没有稳定的最小测试命令;
- 团队经常让 Claude Code 批量改很多文件。
这种情况下,可以先把 hook 改成“提示应运行什么命令”,而不是自动执行。
例如:
|
|
这样不会拖慢 Claude Code,也能把测试习惯固定下来。
一个更实用的策略:按风险分级
可以把自动测试分成三档。
| 风险 | 自动动作 |
|---|---|
| 低风险 | 格式化、lint 单文件、Markdown 检查 |
| 中风险 | 类型检查、相关单测、配置校验 |
| 高风险 | 全量测试、E2E、构建、数据库迁移检查 |
低风险可以放进 PostToolUse 自动跑。中风险可以按文件类型触发。高风险最好放到人工确认、CI 或发布流程里。
Claude Code hooks 的目标不是让本地环境变成完整 CI,而是让 Agent 少犯低级错。
与 CLAUDE.md 怎么分工
CLAUDE.md 适合写原则:
|
|
Hooks 适合写执行:
|
|
也就是说,CLAUDE.md 告诉 Claude Code “应该怎么想”,hooks 负责“到点就做”。两者配合,比只靠提示词稳定。
排错清单
如果 hook 没有运行,按这个顺序排查。
- 在 Claude Code 里输入
/hooks,看事件是否注册。 - 确认
settings.json是合法 JSON。 - 确认事件名写对,例如
PostToolUse、Stop。 - 确认 matcher 能匹配工具名,例如
Edit|Write。 - 确认脚本路径正确。
- macOS/Linux 确认脚本有执行权限。
- Windows 确认 PowerShell 执行策略和引号没问题。
- 脚本里先打印一行
echo hook fired做最小验证。 - 不要一开始就接复杂测试命令。
- 如果输出太长,先改成摘要。
团队使用建议
团队仓库里启用 Claude Code hooks,建议先从最小版本开始。
第一步,只加通知或最终检查提醒。
第二步,对前端格式化、Markdown、类型检查这类低风险命令自动化。
第三步,再按目录或文件类型增加相关单测。
第四步,把全量测试交给 CI,不要强行塞进每次 Claude Code 编辑后。
如果团队成员使用 macOS、Linux、Windows 混合环境,尽量把核心逻辑写成跨平台脚本,或者分别提供 sh 和 ps1,并在 README 里写清楚启用方式。
参考资料
- Claude Code Docs:Automate actions with hooks:https://code.claude.com/docs/en/hooks-guide
- Claude Code Docs:Hooks reference:https://code.claude.com/docs/en/hooks
总结
Claude Code hooks 自动运行测试的关键,不是把 npm test 塞进配置,而是把验证流程拆细。
编辑后用 PostToolUse 做轻量、相关、可重复的检查;结束前用 Stop 做最终提醒或窄范围验证;全量测试仍然交给人工确认和 CI。这样 Claude Code 能及时看到错误,又不会因为每次小改动都跑大测试而变慢、变吵、变贵。
把规则写进 CLAUDE.md,把动作放进 .claude/hooks/,再用 /hooks 验证注册状态。这个组合,比单纯提醒“记得跑测试”可靠得多。