Claude Code の Stop フックで、終わる前にテストを走らせる手順: 失敗が残ったまま終わらない
Claude Code が作業を終える前にテストを走らせるには、Stop フックに npm test を置き、失敗したら終了コード 2 で返します。2026年11月8日に Claude Code 2.1.309 で確かめると、フックがないときは失敗が残ったまま「直しましょうか?」と聞いて終わり、フックがあるときは直してすべてのテストを通してから終わりました。
経緯
AI に足させたコードを出す前に、テストが通っているかを毎回自分で確かめていました。頼んだ作業とは別のところでテストが落ちていても、終わったあとに気づくことがあります。Claude Code 自身に、終わる前にテストを確かめさせる仕組みを作りました。
環境
- macOS 26.6.2、Node.js 24.19.0
- Claude Code 2.1.309(モデルは初めの設定の Claude Opus 5.5)
- 計算の小さなアプリ(
src/calc.jsとテストが2件)。平均を返すaverageには、最後の数を足し忘れる不具合が入っていて、テストが1件失敗している
手順
終わる前にテストを走らせるスクリプトを書く
.claude/hooks/run-tests.sh を作ります。
bash#!/bin/bash
# 終わる前にテストを走らせ、失敗していたら Claude に続けさせる
input=$(cat)
# 2回目以降(フックで続けたあと)は止めない
if echo "$input" | grep -q '"stop_hook_active":true'; then
exit 0
fi
if ! output=$(npm test 2>&1); then
echo "npm test が失敗しています。原因を調べて直してください。" >&2
echo "$output" | tail -30 >&2
exit 2
fi
exit 0
| 部分 | 役割 |
|---|---|
exit 2 | Claude Code に「まだ終わらないで」と返す。エラー出力(>&2)に書いた文が、Claude Code に渡る |
stop_hook_active | フックで続けさせたあとにもう一度呼ばれたときは true になる。ここで止めないと、直せないときに終わらなくなる |
tail -30 | テストの出力の最後だけを渡す。長い出力をそのまま渡さない |
作ったら、実行できるようにします。
terminal$ chmod +x .claude/hooks/run-tests.sh
Stop フックに登録する
.claude/settings.json に、次のように書きます。
json{
"hooks": {
"Stop": [
{ "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/run-tests.sh" } ] }
]
}
}
$CLAUDE_PROJECT_DIR は、プロジェクトの一番上のフォルダーです。Claude Code がほかのフォルダーに移っていても、同じスクリプトを呼べます。
いつもどおりに作業を頼む
フックがないときとあるときで、同じ頼み方をしました。
terminal$ claude -p "src/calc.js に、数の配列の中央値を返す median 関数を足して、テストも足してください。"
| フックなし | フックあり | |
|---|---|---|
| かかった時間 | 36秒 | 45秒 |
| median 関数とテスト | 足した | 足した |
| 前からある average の失敗 | 気づいたが、直さずに終わった | 直した |
終わったあとの npm test | 成功 3、失敗 1 | 成功 6、失敗 0 |
フックがないときも、Claude Code は自分で npm test を走らせ、average の不具合に気づいていました。返事には、ループの条件 i < numbers.length - 1 が原因だと書かれていました。そのうえで「頼まれた作業ではないので、こちらは触っていません。直しましょうか?」と聞いて終わっています。
フックがあるときは、median を足して終わろうとした時点で、フックが「npm test が失敗しています。原因を調べて直してください。」とテストの出力を返しました。Claude Code はそのまま average のループの条件を i < numbers.length に直し、テストを走らせ直してから終わりました。最後の返事は「Stop フックにテストを直すよう言われたので、先ほど報告した average のバグも直しました。」でした。
頼んでいないところを直されたくないときは、文を変える
フックが返す文は、Claude Code への指示になります。頼んだ作業だけを終わらせたいときは、直さずに知らせる文にします。たとえば「失敗しているテストと原因を返事に書いてください」です。
注意点
テストに時間がかかると、終わるたびに待つ
Stop フックは、Claude Code が返事を終えるたびに動きます。テストが長いプロジェクトでは、速く終わるテストだけを走らせるコマンドを用意します。
stop_hook_active を見ないと、終わらなくなることがある
直せない失敗が残ると、フックが何度も続けさせます。上のスクリプトのように、2回目以降は止めない作りにします。公式の説明では、フックで続けさせるのは連続8回までです。
1回ずつの結果で、やり直すと変わることがある
フックがないときに、頼まれていない不具合まで直すこともあります。フックは、それを毎回同じ動きにするための仕組みです。
参考文献
著書
articleClaude Code と Codex を並列で動かしたときの動き: 同じファイルでも書き換えは消えない
articleClaude Code の Stop フックで、終わる前にテストを走らせる手順: 失敗が残ったまま終わらない
articleClaude Code と Codex のスキルの置き場所の動き: .claude/skills と .agents/skills は互いに読まない
articleClaude Code の /security-review で変更を点検する手順: origin/HEAD がないと止まる
articleClaude Code と Codex のスキルを入れる前に中身を確かめる手順: security-audit で見る5か所
articleCloudflare の security-audit スキルを Claude Code と Codex で比較: 3つとも見つけ、進め方に差
articleClaude Code と Codex を並列で動かしたときの動き: 同じファイルでも書き換えは消えない
articleClaude Code の Stop フックで、終わる前にテストを走らせる手順: 失敗が残ったまま終わらない
articleClaude Code と Codex のスキルの置き場所の動き: .claude/skills と .agents/skills は互いに読まない
articleClaude Code の /security-review で変更を点検する手順: origin/HEAD がないと止まる
articleClaude Code と Codex のスキルを入れる前に中身を確かめる手順: security-audit で見る5か所
articleCloudflare の security-audit スキルを Claude Code と Codex で比較: 3つとも見つけ、進め方に差
