playpark
ホーム会社概要サービスソリューションブログお知らせ気軽に相談する
playpark

あらゆる仕事を楽しむ

会社概要サービスソリューション気軽に相談する特定商取引法に基づく表記

© 2019-2026 合同会社playpark All Rights Reserved.

  1. ホーム
  2. ブログ
  3. Claude Code エージェント・安全設計 完全ガイド
  4. 【Claude Code Hooks】テスト自動化で品質を仕組み化 - テスト忘れゼロ件を実現する設定ガイド
ブログ一覧に戻る
技術TipsClaude Code エージェント・安全設計 完全ガイド

【Claude Code Hooks】テスト自動化で品質を仕組み化 - テスト忘れゼロ件を実現する設定ガイド

Claude Code Hooksでテスト忘れゼロ・lint違反ゼロを達成した設定方法を解説。settings.jsonにHookを3つ追加するだけで、AIエージェントの品質管理を自動化できます。コピペで使えるテンプレート付き。

2026年2月19日30分で読める
Claude Codeテスト自動化品質管理AI開発効率化
【Claude Code Hooks】テスト自動化で品質を仕組み化 - テスト忘れゼロ件を実現する設定ガイド

Claude Code Hooks シリーズ

(3記事)
  1. 1.【Claude Code Hooks】テスト自動化で品質を仕組み化 - テスト忘れゼロ件を実現する設定ガイド
  2. 2.【Claude Code Hooks 安全設計】170超のdenyルールとPreToolUseフックで「やらかし」を防ぐ実践パターン
  3. 3.【Claude Code 安全設計】HooksからPermissionsへ — 3つのPythonスクリプトを捨てた理由と移行ガイド

この記事で得られること: settings.jsonに3つのHookを追加するだけで、テスト忘れゼロ・lint違反ゼロを達成する方法。PreToolUse・PostToolUse・Stopの使い分けと、コピペで導入できる設定テンプレートを公開します。

2026-03-07 追記: 本記事で紹介したHooksベースのテスト自動化は、現在Permissions + deny rulesベースの構成に移行しています。

指標導入前導入後
テストなしコミット週3〜5回0回
lint指摘毎PR 2〜3件ほぼ0件
「テスト書いて」の手動指示1日5〜10回不要
dev-flow完遂率約70%約95%

Claude Code Hooksを使えば、settings.jsonに3つのHookを追加するだけで、AIエージェントのテスト未作成コミットを物理的にブロックできます。この記事では、設定5分で導入できる具体的な手順とコピペ可能なテンプレートを公開します。

AIエージェントの「テスト忘れ」問題 — お願いベースの限界

「テスト書いてって言ったのに、なんでテストなしでコミットしてるの...」

AIエージェントにコードを書かせると、実装そのものはかなり良い。ロジックは合ってるし、型も通る。でもテストを書かずにコミットしたり、lintエラーを無視してPRを出してきたりする。

CLAUDE.mdに「必ずテストを書くこと」と書いても、長い会話の途中でトークン圧縮が走ると、その約束は蒸発する。人間の新人エンジニアなら「テスト書いてからマージリクエスト出してね」で済みますが、AIは3分後にはその指示を忘れています。

お願いベースの品質管理には限界がある。 この壁にぶつかったとき、私たちが出した答えが「仕組みで止める」というアプローチでした。

Claude Code Hooksとは?テスト自動化を実現する仕組み

Claude Code Hooksは、AIエージェントのツール実行に対してプログラム的にフックを差し込む仕組みです。settings.jsonに定義すると、AIの「お願い忘れ」に関係なく100%発火します。

3種類のHookを組み合わせることで、テスト自動化の品質ゲートを構築できます。

Hook発火タイミングテスト自動化での役割
PreToolUseツール実行前テストなしコミットをブロック
PostToolUseツール実行後編集のたびに自動lint修正
Stopエージェント停止時最終テスト実行で品質保証

CLAUDE.mdに「テスト書いて」と書くのはお願い。Hookでブロックするのは物理的な壁。お願いの遵守率が体感7割だとしたら、hookは100%です。

あわせて読みたい

AIエージェントが夜中にコードを巡回・修正する「night-patrol」の設計と実践【Claude Code Skills】
技術Tips18分

AIエージェントが夜中にコードを巡回・修正する「night-patrol」の設計と実践【Claude Code Skills】

AIエージェントが深夜にコードベースを自律巡回し、lint警告・テスト失敗・未対応issueを検出→修正→PRまで自動化する「night-patrol」スキルの設計パターンと安全策を解説。

読む

手順1:PreToolUseでテストなしコミットをブロックする

最も効果が大きいのがこのHookです。コミット時に「テストファイルが更新されていなければブロック」します。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git commit:*)",
        "hooks": [
          {
            "type": "command",
            "command": "UNSTAGED=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' '); NOTEST=$(find . -name '*.test.*' -newer $(git log -1 --format=%ci HEAD 2>/dev/null || echo '2000-01-01') 2>/dev/null | wc -l | tr -d ' '); if [ \"$NOTEST\" -eq 0 ] && [ \"$UNSTAGED\" -gt 0 ]; then echo '⛔ テストファイルが更新されていません。テストを書いてからコミットしてください' 1>&2; exit 2; fi; exit 0"
          }
        ]
      }
    ]
  }
}

exit 2で処理が中断され、AIエージェントに「テストを書いてください」というメッセージが返ります。テストなしコミットがゼロになったのは、このHookで物理的にブロックしているので当然です。

あわせて読みたい

AIエージェントが同じミスを繰り返さない3つの設計パターン【Claude Code実装例】
技術Tips34分

AIエージェントが同じミスを繰り返さない3つの設計パターン【Claude Code実装例】

Claude Codeが同じエラーを繰り返す? 構造化ログ・8軸パターン検出・SKILL.md自動修正の3パターンで解決。CLAUDE.mdへの3行追記から始められる実装例付き。

読む

手順2:PostToolUseで編集のたびに自動lint修正する

{
  "PostToolUse": [
    {
      "matcher": "Write|Edit",
      "hooks": [
        {
          "type": "command",
          "command": "npm run lint:fix --silent 2>/dev/null; exit 0"
        }
      ]
    }
  ]
}

ファイルを編集するたびに自動でlint修正が走ります。1回1回は小さな修正ですが、lint警告が積もり積もって最後にまとめて直す地獄を防げます。PRレビューでのlint指摘がほぼゼロになった最大の要因がこのHookです。

手順3:Stop Hookで最終テストを自動実行する

{
  "Stop": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "cd \"$PWD\" && npm test --silent 2>&1 | tail -5; EXIT=$?; if [ $EXIT -ne 0 ]; then echo '❌ テストが失敗しています。修正してから完了してください' 1>&2; exit 1; fi; exit 0"
        }
      ]
    }
  ]
}

AIエージェントが「完了しました」と言って停止する瞬間に、テストを全件実行します。1件でも失敗していたら停止を許可しない。人間が「テスト通った?」と確認する前にプログラムがチェックしてくれるので、レビューの心理的負荷がかなり軽くなります。

3つのHookを組み合わせた品質ゲートの全体像

3つのHookを設定すると、開発フロー全体で品質が自動的に担保されます。

読み込み中...図を読み込み中
層仕組み守備範囲
Layer 1Hook(settings.json)個別操作の瞬間チェック
Layer 2Skill(dev-validate)ワークフローの節目チェック
Layer 3Subagent(Task委譲)コンテキスト節約+専門チェック

Layer 1: Hook — 条件反射的なガードレール

Hookは無条件で発火するのがポイントです。AIの判断を介さない。3つが常時稼働していれば、「テストなしでコミットされた」事故はゼロになります。ただし、Hookは軽い処理に向いています。複雑なテスト実行や問題の切り分けはHookの守備範囲外です。

Layer 2: Skill — ワークフロー内のチェックポイント

dev-kickoffの6フェーズ開発フローの中で、dev-validateはPhase 4に位置します。

Phase 1: git-prepare(worktree作成)
    ↓
Phase 2: dev-issue-analyze(要件分析)
    ↓
Phase 3: dev-implement(実装)
    ↓
Phase 4: dev-validate --fix  ← ここ
    ↓
Phase 5: git-commit(コミット)
    ↓
Phase 6: git-pr(PR作成)

実装が終わったら即座にdev-validateが走り、テスト失敗やlintエラーがあればPhase 3に差し戻し。--fixオプション付きなので、自動修正可能な問題はその場で直してくれます。

Layer 3: Subagent — コンテキストを消費しない専門エージェント

テスト実行のログ出力は長い。テストが20件あれば、そのログだけでコンテキストウィンドウの相当な部分を消費します。

メインエージェント(dev-kickoff)
  │
  ├── Phase 3: 実装に集中
  │
  └── Phase 4: Task(quality-engineer) に委譲
       └── dev-validate --fix --worktree $PATH
           ├── テスト実行(ログはsubagentのcontextに収まる)
           ├── lint実行
           └── 結果JSONだけメインに返す

メインエージェントのコンテキストを汚さずに、品質チェックの結果だけを受け取る。テストが100件あっても、メインに返るのは「pass」か「fail」かの小さなJSONだけです。

dev-validateスキル:テスト自動化のエンジン

Hookが「いつ検証するか」を制御する門番なら、dev-validateは「何を検証するか」を担当するエンジンです。

$SKILLS_DIR/dev-validate/scripts/validate.sh [--fix] [--strict] [--worktree <path>]
オプション説明
--fixlint問題を自動修正
--strictlintがスキップされたら失敗扱い
--worktree検証対象のworktreeパス

内部ではプロジェクトタイプを自動検出して、適切なコマンドを実行します。

# テスト実行:プロジェクトの設定ファイルで言語を自動判定
run_tests() {
    if [[ -f "package.json" ]]; then
        if grep -q '"test"' package.json 2>/dev/null; then
            local pm="npm"
            [[ -f "yarn.lock" ]] && pm="yarn"
            [[ -f "pnpm-lock.yaml" ]] && pm="pnpm"
            $pm test >/dev/null 2>&1 && TEST_RESULT="passed" \
              || { TEST_RESULT="failed"; TEST_EXIT=1; }
        else
            TEST_RESULT="no_test_script"
        fi
    elif [[ -f "Cargo.toml" ]]; then
        cargo test >/dev/null 2>&1 && TEST_RESULT="passed" \
          || { TEST_RESULT="failed"; TEST_EXIT=1; }
    elif [[ -f "go.mod" ]]; then
        go test ./... >/dev/null 2>&1 && TEST_RESULT="passed" \
          || { TEST_RESULT="failed"; TEST_EXIT=1; }
    elif [[ -f "pytest.ini" ]] || [[ -f "pyproject.toml" ]]; then
        pytest >/dev/null 2>&1 && TEST_RESULT="passed" \
          || { TEST_RESULT="failed"; TEST_EXIT=1; }
    fi
}

出力はJSON形式で、Hookやワークフローから判定しやすい設計です。

cat <<JSONEOF
{
  "worktree": "$WORK_DIR",
  "changes": {"files": $FILES_CHANGED, "insertions": $INSERTIONS, "deletions": $DELETIONS},
  "tests": "$TEST_RESULT",
  "lint": "$LINT_RESULT",
  "overall": "$OVERALL",
  "exit_code": $EXIT_CODE
}
JSONEOF

overall: "fail"なら先に進まない、tests: "failed"ならテスト修正に戻る。フルソースはGitHubリポジトリで公開しています。

あわせてチェック

この技術の導入、お手伝いします

記事で紹介した技術やツールの導入でお悩みですか?具体的な課題をお聞かせください。

気軽に相談する

コピペで使えるsettings.jsonテンプレート

ミニマル構成(個人開発・小規模プロジェクト向け)

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git push:*)",
        "hooks": [
          {
            "type": "command",
            "command": "BR=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo ''); case \"$BR\" in dev|develop|main|master) echo '⛔ 保護ブランチへの直接pushはブロックされています' 1>&2; exit 2;; esac; exit 0"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint:fix --silent 2>/dev/null; exit 0"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "npm test --silent 2>&1 | tail -3; EXIT=$?; if [ $EXIT -ne 0 ]; then echo '❌ テスト失敗' 1>&2; exit 1; fi; exit 0"
          }
        ]
      }
    ]
  }
}

これだけで「保護ブランチpushブロック + 自動lint + 停止時テスト」の3点セットが稼働します。

フル構成(チーム開発・Skill連携込み)

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git push:*)",
        "hooks": [
          {
            "type": "command",
            "command": "BR=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo ''); case \"$BR\" in dev|develop|main|master) echo '⛔ 保護ブランチへの直接pushはブロックされています' 1>&2; exit 2;; esac; exit 0"
          }
        ]
      },
      {
        "matcher": "Bash(git commit:*)",
        "hooks": [
          {
            "type": "command",
            "command": "RESULT=$($SKILLS_DIR/dev-validate/scripts/validate.sh 2>/dev/null); OVERALL=$(echo \"$RESULT\" | grep -o '\"overall\":\"[^\"]*\"' | cut -d'\"' -f4); if [ \"$OVERALL\" = 'fail' ]; then echo '⛔ dev-validate失敗。テスト/lintを修正してください' 1>&2; echo \"$RESULT\" 1>&2; exit 2; fi; exit 0"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint:fix --silent 2>/dev/null; exit 0"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "RESULT=$($SKILLS_DIR/dev-validate/scripts/validate.sh --strict 2>/dev/null); OVERALL=$(echo \"$RESULT\" | grep -o '\"overall\":\"[^\"]*\"' | cut -d'\"' -f4); if [ \"$OVERALL\" = 'fail' ]; then echo \"$RESULT\" 1>&2; echo '❌ 品質チェック失敗。修正してから完了してください' 1>&2; exit 1; fi; exit 0"
          }
        ]
      }
    ]
  },
  "permissions": {
    "deny": ["Bash(rm -rf:*)", "Bash(sudo:*)", "Bash(git push --force:*)"]
  }
}

フル構成では、PreToolUseのコミット前チェックにdev-validateスキルを直接呼び出し、Stop Hookでも--strictオプション付きで実行する厳格モードです。

Hookカスタマイズのポイント

matcherのパターン設計

matcherは「どのツール実行にhookを適用するか」を指定します。

"Bash(git commit:*)"   → git commitコマンドにマッチ
"Bash(git push:*)"     → git pushコマンドにマッチ
"Write|Edit"           → ファイル書き込み・編集にマッチ
"Notebook.*"           → NotebookRead, NotebookEdit等にマッチ
"mcp__memory__.*"      → MCPサーバーのツールにマッチ

コミット・プッシュ系は個別指定、編集系はまとめてマッチが実用的なバランスです。

exit codeの使い分け

exit code意味AIエージェントの挙動
0成功(続行)そのまま処理を続ける
1警告(レポート)警告メッセージを認識するが続行
2ブロック(中断)処理を中断し、エラー内容を報告

PreToolUseでexit 2を返すと、ツール実行そのものが中断されます。PostToolUseの場合はツール実行済みなので、exit 2は「結果に問題がある」というシグナルになります。

導入してわかった予想外の効果

  • PostToolUseのlint:fixが思ったより効く: 1回1回は小さな修正。でもPR作成時のlintエラーがほぼゼロになった
  • Stop Hookの心理的安全性: 「AIが完了と言ったならテスト通ってる」と信頼できるようになった
  • Subagent委譲のコンテキスト節約: テストが多いプロジェクトでは顕著。メインエージェントが実装に集中できる

まだ課題として残っていること

  • Hookの実行時間: validate.shをフルで走らせると数十秒かかるプロジェクトがある
  • matcherの設計: プロジェクトごとにツール名が違う場合の対応が途上
  • 偽陽性の管理: 外部API依存テストがHookで落ちて、関係ない修正がブロックされることがある

まとめ

Claude Code Hooksを使ったテスト自動化は、「AIにテストを書かせる」のではなく「テストを書かないと先に進めない構造にする」 というアプローチです。

「お願い」で品質を担保する時代は終わりました。AIエージェントとの共同作業で品質を維持するには、人間のコードレビューと同じく、仕組みで担保するのが現実的です。

まずはミニマル構成のsettings.jsonテンプレートから試してみてください。設定に5分、効果は半永久。保護ブランチpushブロックだけでも、「テスト通ったっけ...」の心配が1つ消えます。

なお、本記事で紹介したHooksベースの品質ゲートは、その後Permissions + deny rulesベースの構成に移行しました。


あわせて読みたい

  • 【2026年版】AIコーディングツール完全比較 — Claude Code・Codex・Antigravityの選び方
  • 【Claude Code】settings.json完全ガイド — CLAUDE.md・Hooks・permissionsの設定を深掘り
  • 【Claude Code × Codex × Antigravity】AIコーディングツールのSkillsを統一管理する方法 — Skills共有の実装方法

→ 気軽に相談する


Claude Code エージェント・安全設計 完全ガイド — この記事を含む10本の記事で、エージェント活用・Hooks安全設計・並列開発を体系的に解説しています。

3 / 10 記事
前の記事
【Claude Code】worktree並列開発の自動タスク分解と統合 - dev-decomposeで「分けて、束ねる」を設計する
次の記事
【Claude Code Hooks 安全設計】170超のdenyルールとPreToolUseフックで「やらかし」を防ぐ実践パターン
シリーズ一覧を見る
Claude Code Hooks シリーズ — 1 / 3 記事
次の記事
【Claude Code Hooks 安全設計】170超のdenyルールとPreToolUseフックで「やらかし」を防ぐ実践パターン

この技術が解決した業務課題

記事の技術が実際のプロジェクトでどう活かされているかをご紹介します

【自社導入事例】ブログ運用を完全自動化 - GitHubリポジトリから記事・サムネイル・SNS投稿まで

「ブログ書くのしんどい」「SNS投稿めんどくさい」を解決。GitHubリポジトリから記事生成、サムネイル作成、SNS投稿文まで自動化した、playpark自身の導入事例を紹介します。

事例を読む

【AI採用管理】Gemini API × Next.jsで書類選考を自動化した受託開発事例

Gemini APIとNext.jsで採用書類選考を自動化。中小企業の採用DXをplayparkが受託開発で支援した事例をご紹介します。

事例を読む

【AIシフト管理】AIが提案して店長が決める - 「全自動が不安」なサロンのためのシフト最適化

「AIに全部任せるのは怖い」という店長さんへ。Shift Budの「AI提案→人が判断」ワークフローなら、AIの提案と差分を確認してから採用できます。完全自動化ではなく、人の判断を残したシフト管理の新しいかたちを紹介します。

事例を読む
AI開発の導入支援

Claude CodeやAIコーディングツールの導入・カスタマイズでお困りですか?playparkでは、AI開発環境の構築から運用まで、実践に基づいた技術支援を行っています。

サービス
AI開発について相談する
ブログ一覧に戻る

関連記事

すべての記事
【Claude Code × Codex】共存運用を調べて試してみた — Skills統一管理とプロジェクト別選定フレームワーク
実験レポート
2026年3月30日25分で読める
【Claude Code × Codex】共存運用を調べて試してみた — Skills統一管理とプロジェクト別選定フレームワーク

Claude Codeヘビーユーザーが、Codexとの共存運用を調査・検証。Skills統一管理のsymlink共有やプロジェクト別ツール選定マトリクスなど、実際に試した範囲で正直にレポートします。

Claude CodeCodexAIコーディングツール+3
AIエージェントが同じミスを繰り返さない3つの設計パターン【Claude Code実装例】
技術Tips
2026年3月26日34分で読める
AIエージェントが同じミスを繰り返さない3つの設計パターン【Claude Code実装例】

Claude Codeが同じエラーを繰り返す? 構造化ログ・8軸パターン検出・SKILL.md自動修正の3パターンで解決。CLAUDE.mdへの3行追記から始められる実装例付き。

Claude CodeAIClaude Code Skills+2
【SEO自動化】GA4 × GSC × Google Trendsでコンテンツを自動提案する — エンジニアが作るSEO企画パイプライン
技術Tips
2026年3月25日31分で読める
【SEO自動化】GA4 × GSC × Google Trendsでコンテンツを自動提案する — エンジニアが作るSEO企画パイプライン

GA4・GSC・Google Trendsのデータを3段パイプラインで統合し、SEOスコアリングで記事ネタを自動提案するスキル群の設計を解説。マーケ感覚ゼロのエンジニアでも、データが「次に書くべき記事」を教えてくれる仕組みを作りました。

Claude CodeClaude Code SkillsSEO+3

この技術、実際の現場ではこう使われています

記事で紹介した技術が、実際のビジネス課題をどう解決したか。導入事例で具体的なイメージをつかめます。

導入事例を見る気軽に相談する