0:00 0:00
記事
Claude Codeで古いテストコードを整理する方法
実装に追従できず腐ったテストコードを、Claude Codeで安全に整理する手順を整理します。不要テスト・重複テスト・遅いテスト・flaky testの見分け方、削除と修正の判断基準、テストを壊さずに直すための依頼文までを公式仕様と現場運用の両面でまとめた、テストのリファクタリングをしたい上級者向けの実務ガイドです。
Claude Codeでテストを書き足し続けると、いつのまにか実装に追従できていないテスト、重複したテスト、毎回数分かかる遅いテストがたまります。本記事は、腐ったテストを「実装コードと同じ慎重さ」で整理するための手順と依頼文を整理します。
結論:テストの整理は「分類してから」始める
テストコードの整理でいきなり「テストを綺麗にして」と頼むと、Claude Codeは通っているテストを消したり、アサートを弱めて「速くした」ことにしたりします。テストは仕様のスナップショットなので、実装コード以上に慎重に扱います。
整理は次の順序で進めます。
- 分類する:腐ったテストを4タイプに仕分ける
- 判断する:削除・修正・据え置きのどれかを決める
- 直す:1コミット1意図で、挙動を変えずに直す
- 検証する:カバレッジでなく「バグを捕まえる力」で確認する
このうち判断は人間が持ちます。AIに任せるのは分類の下書きと、修正の実装です。
腐ったテストの4タイプ
整理の前に、何が問題なのかを4つに分けます。対処がそれぞれ違うからです。
| タイプ | 症状 | 主な対処 |
|---|---|---|
| 不要テスト | 消えた機能のテスト、重複、自明アサート | 削除 |
| 重複テスト | 同じ経路を別の名前で何度もテスト | 統合 |
| 遅いテスト | 1件で数秒〜数分。CI全体を遅くする | 高速化・分離 |
| flaky test | 実装を変えていないのに通ったり落ちたり | 原因特定して修正 |
「落ちているテスト」と「腐ったテスト」は別物です。落ちているテストはまずバグの可能性を疑います。腐ったテストは、通っていても価値がない、または信頼できないテストを指します。
ステップ1:分類する
最初に棚卸しします。機械的に取れる情報から始めます。
実行時間の長いテストは、テストランナーのレポート機能で特定できます。
npx vitest run --reporter=verbose --slowTestThreshold=1000 describe.skipやit.skipで止まったまま放置されたテストも洗い出します。
grep -rn -E '(describe|it|test)[.]skip' tests/ src/ そのうえで、内容の分類はClaude Codeに下書きさせます。
目的: テストの棚卸し表を作る
対象: @tests/ 配下のテストファイル
依頼:
- 各テストファイルについて、次を表にする
- ファイル名
- テスト件数
- skip されているテスト数
- 同じ実装関数を対象にした他ファイルとの重複の有無
- アサートが0件、または自明(toBeDefined だけ等)なテストの数
- 判断はしない。事実の列挙だけ
禁止事項:
- テストの削除・修正
- 「これは不要」などの主観的な決めつけ
棚卸しは事実集めに留め、削除の判断はまだしません。
ステップ2:削除・修正・据え置きを判断する
棚卸し表ができたら、テストごとに次の3択を人間が決めます。
- 削除:対象の機能がもう存在しない/別テストと完全に重複/アサートが空または自明
- 修正:テストの意図は正しいが、実装変更に追従できていない/flaky
- 据え置き:遅いが重要、たまにしか動かないが必要。今は触らない
判断で迷ったときの原則は「このテストが落ちたら、それはバグを意味するか?」です。イエスなら残す、ノーなら削除候補です。通っているだけで何も検証していないテストは、むしろ「直したつもり」の油断を生むため害になります。
削除候補が「本当に重複か」を確かめるには、片方を一時的に外して、もう片方がカバレッジ上の同じ行を通るかを見ます。
ステップ3:挙動を変えずに直す
修正と判断したテストは、「Claude Codeで既存コードを壊さずリファクタリングする依頼文」と同じ原則で直します。テストの「検証している内容」を変えないことが鉄則です。
目的: tests/order.test.ts の腐ったテストを修正する
背景: createOrder のシグネチャ変更にテストが追従できておらず、
古いプロパティ名で書かれている
依頼:
- 古いプロパティ名を現行のものに合わせる
- テストが「検証している内容」は変えない
- 重複している2件("creates order" と "order is created")は
1件に統合する
完了条件:
- npm test が緑
- 修正後のテストが、わざと実装にバグを入れると落ちることを確認
(ミューテーションを1つ入れて落ちるか見る)
禁止事項:
- アサートを弱めて通す(toEqual を toBeDefined に変える等)
- skip で逃げる
- テスト対象の実装コードを変更する
特に注意するのは「アサートを弱めて通す」改ざんです。git diff tests/を人間が必ず読み、toEqualがtoBeDefinedに化けていないかを確認します。AIが書きがちな危ないテストの見分け方は「Claude Codeにテストコードを生成させるときの依頼文と注意点」に詳しくまとめています。
flaky testの直し方
flaky testは「腐った」というより「壊れている」テストです。原因を特定せずにretryで握りつぶすと、本物のバグを見逃します。よくある原因は次のとおりです。
| 原因 | 兆候 |
|---|---|
| 時刻依存 | Date.now()や日付境界で落ちる |
| 順序依存 | 単体では通るが、他テストと一緒だと落ちる |
| 非同期の待ち不足 | await漏れ、固定sleepでの待ち合わせ |
| 共有状態 | グローバル変数・DB・ファイルをテスト間で共有 |
| 外部依存 | ネットワーク・実APIを叩いている |
順序依存や非同期が絡む場合は、レースコンディションの調査と同じ進め方になります。詳しくは「Claude Codeでレースコンディションを疑うときの調査プロンプト」を参照してください。flakyを直すときも、まず再現条件(繰り返し実行、ランダム順実行)を作ってから依頼します。
ステップ4:カバレッジでなく「捕まえる力」で検証する
テスト整理の成果を、カバレッジの数値だけで測ってはいけません。カバレッジは「コードが実行されたか」を示すだけで、「バグを捕まえられるか」は示しません。
整理後の確認は次の観点で行います。
- 整理後もCI全体が緑
- 実装にわざとバグ(ミューテーション)を1つ入れると、関連テストが落ちる
- CI全体の実行時間が短くなった(遅いテストを直した場合)
skipの総数が減った
「テストを消したらカバレッジが下がった」は、消したテストが無価値だったなら問題ありません。逆に「カバレッジは保ったがアサートを弱めた」は改悪です。テスト整理は技術的負債の返済の一種なので、進め方の全体像は「Claude Codeで技術的負債を増やさないリファクタリング計画」も合わせて参考になります。
やってはいけないこと
- 「テストを綺麗にして」と丸投げする:通っているテストが消える
- アサートを弱めて「速くした・直した」とする:検証能力を失う
- flaky testを
retryで握りつぶす:本物のバグを見逃す - 削除と修正を1コミットに混ぜる:レビューで差分が追えない
- カバレッジ数値だけで成果を判断する:実行されただけで検証はされていない
チェックリスト
- 腐ったテストを4タイプ(不要・重複・遅い・flaky)に分類した
- 「落ちたらバグを意味するか」で削除・修正・据え置きを判断した
- 棚卸し(事実集め)と判断を別ステップに分けた
- 修正時にアサートを弱めていないか
git diff tests/を読んだ - flaky testは原因を特定してから直した(retryで逃げない)
- 削除・修正・統合をそれぞれ別コミットにした
- ミューテーションを入れて関連テストが落ちることを確認した
- 成果をカバレッジ数値だけで判断していない
次に読むおすすめ記事:
- 「Claude Codeにテストコードを生成させるときの依頼文と注意点」:AIが書きがちな危ないテストの見分け方
- 「Claude Codeで既存コードを壊さずリファクタリングする依頼文」:挙動を変えずに直す依頼の型
- 「Claude Codeで技術的負債を増やさないリファクタリング計画」:負債返済としてのテスト整理の位置づけ