test-audit について
テストの作成やレビューを行う開発者向けのスキルです。各テストがユーザーに関わる不具合を独立して検出できるかを重視し、設計、回帰テスト、モック、既存テストの監査基準を示します。
主な機能
- 01テスト前に確認する四つの問い
- 02回帰テストの検証
- 03モックの指針
- 04ミューテーションによるカバレッジ確認
- 05根拠に基づくテスト監査
活用シーン
- 01新しいテストが動作を保護するかの評価
- 02回帰テストが不具合を再現するかの検証
- 03記録した根拠に基づくテストの整理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ t0msilver/ skills --skill test-auditインストール後、Claude Code で/test-auditを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
reference/campaign.mdjunk-patterns.mdsources.md詳細
テスト監査
テストが保守コストに見合うのは、誰かがバグと呼ぶような不具合を検出できる場合です。この基準は、テストを書くときにも、既存のテストを削除するか判断するときにも適用されます。サブシステム全体のテストを一度の変更で整理する場合は、まず reference/campaign.mdを読んでください。
テストを書く前に
次の4点すべてに答えてください。答えがひとつでも欠けている場合は、まだテストを追加しないでください。
- どのような本番コードの変更で失敗し、その変更はバグですか、それとも仕様上の判断ですか? 意図的な判断だけで失敗するのであれば(定数の値、正確な文言、プライベートな構造など)、それは変更検出器です。再設計には反応しますが、バグを見逃します。その判断に依存する動作をテストしてください。
MAX_RETRIES == 5ではなく、「6回目の試行は行われない」をテストします。 - 期待値の根拠は何ですか? リテラル、具体的な例、または仕様を使ってください。テスト対象のコードやそのヘルパーを使ってはいけません。
expect(f(x)).toBe(f(x))は必ず成功します。実装と同じ計算式で値を導き直す期待値は、その計算式のバグまで共有します。 - 既存のテストでは、なぜすでに検出できないのですか? 各契約には、通常はパブリックインターフェースという最も強力な境界で、それを担当するテストをひとつ設けます。2つ目の層が必要なのは、担当テストでは到達できないリスクがある場合です。たとえば、トランスポートやライフサイクルの障害が該当します。よく似たテストを追加するより、既存のテーブルテストに行を追加することを優先してください。
- 本番コードを呼び出す側には不要な接続点が必要ですか? テストのために追加するエクスポート、フラグ、ゲッター、リセット用フック、
destroy()などが該当します。必要な場合は、実際の境界でテストしてください。テストのクリーンアップにだけ必要なものは、テストユーティリティに置いてください。
次に、避けるべきパターンに照らして確認してください。一致する場合、保持基準に、そのテストが独立して守る契約が明記されていない限り、ゲートを通過できません。動作を保つリファクタリングで失敗するテストは、実装を検証しています。マージする前に、担当する境界でテストを書き直してください。
フレームワークをテストしてはいけません(ルーターが登録したハンドラーを呼び出すことを検証するなど)。また、単純なコードもテストしてはいけません。コンストラクター、ゲッター、単純な転送処理は、検証、正規化、デフォルト設定、導出、または副作用のいずれかを行う場合に限り、テストする価値があります。
回帰テスト
回帰テストは、修正前のコードでバグの説明どおりの理由で失敗し、修正後に成功しなければなりません。実際に修正前のコードで実行して確認してください。バグが原因ではないエラー(インポートの失敗、セレクターの欠落、セットアップの破損など)は、何の証明にもなりません。バグと同じ理由で失敗するまで修正してください。一度も失敗しなかった回帰テストが証明するのは、修正ではなくモックです。テストは担当する境界にひとつ書いてください。同じシナリオを、通過するすべての層で繰り返してはいけません。
モック
- モック自体を検証してはいけません。モックが存在すれば成功し、削除すると失敗するアサーションは、コードについて何も示しません。
- メソッドをモックする前に、その副作用を列挙してください。テストが依存する層より下にある、遅い処理や外部依存の層をモックし、メソッド自体はモックしないでください。
- モックの応答は、テストが読み取るフィールドだけでなく、実際の完全な構造を反映させてください。不完全なモックは、統合時に問題が起きてもテストを通過します。
- 引数、呼び出し回数、または順序が契約である場合は、それらをアサートしてください。各分岐(成功、エラー、不正な形式)にそれぞれ固有のフィクスチャを用意し、誤った分岐でテストを通過できないようにしてください。
- モックのセットアップがテスト本体より大きくなった場合や、モックが必要な理由を説明できない場合は、代わりにフェイクのネットワークまたはファイルシステムと実際のコンポーネントを使ってください。
完了前に
本番コードに誤った定数や引数、誤った分岐、欠落した副作用、空の戻り値を設定した場合や、空、ゼロ、null、未認証、不正な形式の入力に対するチェックを削除した場合を、頭の中でシミュレーションしてください。それぞれに対して、少なくともひとつのテストが失敗する必要があります。何のテストも検出できない変更は、保護されていない動作か、恒真テストがあることを示しています。
既存テストの監査
- ルートおよびスコープ対象の
AGENTS.md/CLAUDE.mdを読み、各候補について、テスト全体、対象となる本番コード、その呼び出し元、重複するテスト、CI の実行対象、および存在理由を示すgit logを確認します。依存関係に基づく動作を主張している場合は、依存関係のソースコードまたは型定義を読みます。 - 調査は読み取り専用で行います。根拠の薄い候補を大量に挙げるより、十分な根拠のある候補をいくつか選びます。対象範囲が広い場合は、領域ごとに分けて読み取り専用エージェントを並行して実行します。
- 編集前に、各候補について根拠を記録します。項目が欠けている場合は、削除できる状態ではありません。
- 変更ごとに、まとまりのある単位で編集します。削除によって不要になったテスト専用のエクスポート、フラグ、ラッパー、本番コードのデッドパスは、エイリアスとして残さず削除します。残す回帰テストは、適切なテストスイートに移します。同じ実装を言い換えて再確認するテストは追加しません。
- 最小限の担当テストと関連テストを実行し、その後、変更ファイルに対してリポジトリで必須のチェックを実行します。ソーステキストのアサーションを削除した場合は、実際の契約を担うスクリプトまたはドライランを実行します。
- 本番コードとテストの行数を別々に報告し(
git diff --numstat)、ジャンクに見えたものの残したテストと、その理由も報告します。
注意点
- 静的であることや時間がかかることは、削除の理由になりません。 ソーステキストを読むテストが、ユーザー向けのキー、バイト数、パスを独立して守る最も低コストな方法である場合があります。契約が変わったときに失敗し、識別子を変更しても機能するなら残します。それ以外のテストも、保持基準に記載されたものは残します。
- ベースブランチで失敗する削除候補は、製品の不具合である可能性があります。 再現して本番コードを修正し、問題を見つけたテストを削除してはいけません。
- テストは名前ではなく、アサーションで判断します。 「ウィンドウを終了する」という名前のテストが、実際にはウィンドウがクリアされないことを一度確認していた場合もあります。
- 負のテストが適切な理由で失敗するか確認します。 別のガードによる拒否や、本番の処理経路が到達しない拒否は、何も守らないままテストを通過してしまいます。
- 件数を減らすために削除してはいけません。 判断に迷う候補は残します。残すテストへの確信を優先します。
- 同じチェックアウトでテストスイートの実行中にテストを変更してはいけません。 ウォッチモードや並列ランナーが編集中のファイルを読み込み、実際には存在しない失敗を報告することがあります。