test-quality-audit について
ユーザーや呼び出し元が依存する動作をテストが保護し、現実的な回帰を検出するか監査するスキルです。根拠に基づく分類と簡潔な報告を導きます。
主な機能
- 01動作上の契約に基づくテスト評価
- 02カバレッジと実行条件の確認
- 03Keep、Fix、Cut、Addによる分類
- 04現実的な回帰への感度確認
- 05根拠を軸にした所見の構成
活用シーン
- 01プルリクエストで変更されたテストのレビュー
- 02報告された回帰をテストが検出するかの評価
- 03スキップや任意実行によるテスト不足の特定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ marcellocurto/ skills --skill test-quality-auditインストール後、Claude Code で/test-quality-auditを入力して読み込まれたか確認します。
詳細
テスト品質の監査
テストを残す価値があるのは、ユーザーや呼び出し元が依存する動作、つまり現実的な契約違反によって失敗するときです。すべてのテストをこの基準で評価してください。カバレッジ、テスト数、テストを先に書いたかどうかは判断材料になりません。失敗が実際の不具合を示す小規模なスイートは、大規模なスイートより優れているため、デフォルトでテストの追加を求めないでください。
テストが保護する契約がない、または保護するものに比べて保守コストが高いことが根拠から明らかな場合に限り、そのテストを弱いと判断してください。判断に必要なコンテキストが不足している場合は、テストの価値が低いと決めつけず、その旨を伝えてください。
読むもの
まずレビュー対象のテストを確認し、その後、評価に必要なものだけを読みます。
- テスト対象の実装と、公開されている、またはユーザーから確認できる動作
- 重要な分岐と失敗経路
- フィクスチャ、モック、ファクトリー、スナップショット、ヘルパー
- 同じ動作を対象とする既存のテスト
- 入手できる場合は、PR の意図、バグ報告、既知のリグレッション
- テストの実行を決めるコマンド、選択ルール、前提条件
- 外部境界:データベース、API、認証、キュー、ファイルシステム、時刻、乱数、ネットワーク
テストが主張する動作、実際の依存関係、リスクのある分岐、または周辺にあるより強力なカバレッジが不明確な間だけ、読み進めてください。
方法
各テストまたはテストグループについて、次の問いに答えてください。
- どの契約を保護すると主張していますか?
- 実際には何を保護していますか?
- どのような現実的なリグレッションで失敗し、そのリグレッションは重要ですか?
- テストが成功したまま、契約が破られる可能性はありますか?
- 無害なリファクタリングで失敗する可能性はありますか?
- 呼び出し元が依存する結果を検証していますか。それとも、ファイル、キー、オプション、呼び出し、行など、変更によって生じたものが存在することだけを検証していますか?差分を固定するだけのテストは契約を保護しません。修正済みの動作が再び壊れたときに失敗するリグレッションテストは、契約を保護します。
- 適切なレベルにありますか:ユニット、統合、コントラクト、エンドツーエンド、または該当なし?
- 主張されている検証では、関連する条件下で実際にテストが実行されましたか?
変更されたテスト
変更前と変更後で、テストが何を保護していたかを比較してください。以前のテストが検出でき、新しいテストでは検出できない現実的なリグレッションは何ですか?変更されたアサーション、フィクスチャ、モック、スナップショット、スキップ設定、構成をまとめて確認してください。保護の喪失が許容されるのは、判断によって契約が変更された場合、または以前のテストが誤りだったと示された場合に限られます。インターフェースが変わっただけでは、失敗ケースを削除する理由になりません。
動作が削除された場合、それに伴って削除されたテストは保護の喪失には当たりません。残りのスイートで、削除された領域に依存していたものが引き続きカバーされているか確認してください。
感度の確認
重要なテストが、検出すると主張するリグレッションで失敗するかどうか不明な場合は、既存の「修正前に失敗していた」という証拠を確認するか、既知の不具合があるバージョンに対して実行してください。一時的な不具合を導入すれば判断できる場合は、使い捨てのコピーで実施し、テストは変更せず、コピーを元に戻して、確認した内容を報告してください。レビュー対象のチェックアウトは変更せず、ミューテーションテスト用のインフラストラクチャも要求しないでください。不具合がある状態でもテストが成功した場合に否定されるのは、その不具合に対する有効性だけです。
分類
- 維持:契約を保護し、現実的なリグレッションで失敗する。
- 修正:意図には価値があるが、実装が弱い。観測可能な動作またはリスクのある境界を中心に書き直す。
- 削除:契約を保護していない、または保護するものに比べて保守コストが高く、書き直す価値のある意図もない。冗長、同語反復、カバレッジだけを目的とするテスト、および互換性の約束を定めていない静的コンテンツ、文言、ナビゲーション構造、重要でない構成のテストを含む。
- 追加:契約がテストされておらず、現実的なリグレッションが起こり得る場合。削除、設計の検討、プロトタイプ、静的コンテンツ、文言、構成については、呼び出し元が依存する互換性の約束を構成が担っている場合を除き、追加を推奨しない。
調査すべきパターン
このリストにあるパターンは、詳しく調べる理由になります。変更を勧める前に、契約、テストが検出または見逃す回帰、具体的な保守コストを明らかにしてください。その契約について有用な根拠を示すパターンは維持してください。
- 不在のアサーション。 機能、ルート、オプション、メニュー項目、またはデフォルトが存在しなくなったことを確認するテストは、契約を保護しないため削除してください。ただし、認証なしではエンドポイントに到達できない、破壊的な操作はデフォルトで無効になっているなど、不在そのものが保証されている場合を除きます。
- 呼び出し、回数、順序のアサーション。 重複送信に対してメッセージを正確に1件送信する、必須のプロトコル順序に従うなど、やり取りが契約である場合は維持してください。保証された結果に影響がないのに、非公開のヘルパー呼び出しを固定している場合は削除するか修正してください。
- 定数とフィクスチャ。 公開された形式、プロトコル値、互換性要件のチェックは維持してください。フィクスチャで制御される値をそれ自身と比較するアサーションや、重要でない設定を繰り返すアサーションは削除してください。ラッパーやゲッターがテストする価値のある動作を担う場合もあります。その動作に基づいて判断してください。
- スナップショット。 安定した意味のある出力を保護し、変更が意味に基づいてレビューされる場合は維持してください。ノイズとなる付随的な出力、誰も気づかなかった契約の変更、回帰を受け入れてしまう一括スナップショット更新は調査してください。スナップショットを使うこと自体は弱点ではありません。
- モックなどのテストダブル。 契約を分離したり、失敗条件を制御したりする場合は維持してください。テスト対象の動作を置き換えている場合や、テストが検証すると主張する連携、永続化、変換の不具合を隠している場合は指摘してください。
- セットアップと機能の選択。 サポート対象のワークフローでは保証されない状態の初期化、機能の有効化、設定の提供を行うフィクスチャは指摘してください。有効な準備済み状態のテストは維持できますが、準備完了や利用可能であることの証明にはなりません。エラー処理を徹底的にテストしていても、成功経路がテストされていなかったり、壊れていたりすることがあります。
- 実行上の欠落。 オプトイン、スキップ、予期された失敗を示すマーカー、必須のインフラストラクチャを調べてください。検証コマンドで実行されないテストスイートは、成功の主張を裏付けられません。必須の決定論的テストは必須コマンドで実行し、前提条件が欠けている場合は明確に失敗するよう勧めてください。任意のライブサービスチェックは明示的なままにしてください。
- 計算された期待値。 期待値が実装とは独立して導出されていることを確認してください。実装の計算を繰り返すと、そのバグが隠れてしまいます。契約に基づいて導出される計算済みの期待値は問題ありません。
- 重複するテストや内部テスト。 冗長または実装依存と判断する前に、テストが何を確認しているかを比較してください。他のテストでは見つからない重要な不具合を検出する内部テストは維持してください。無害なリファクタリングで壊れたり、実際の回帰があっても合格したりする、非公開の構造に対するアサーションは指摘してください。
- 古いAPIを対象とするテスト。 置き換えられた本番APIやアダプターが、テストで使われ続けていることだけを理由に残っていないか確認してください。削除を勧める前に、他の呼び出し元と互換性要件を調べてください。古いAPIが不要になった場合、有用なテストは修正対象として分類し、同じ動作を確認しながら置き換え先に移してください。置き換えられておらず、テストからだけ直接呼び出される内部インターフェースについては、
audit-code-complexityスキルで複雑さの問題を検討してください。ここでは、そのインターフェースのテストが保護する動作に基づいて判断してください。 - 失敗とタイミングのカバレッジ。 現実的な不具合を隠したり、結果の信頼性を損なったりする場合は、失敗経路の欠落、スリープ、制御されていないタイミングを指摘してください。あらゆるエッジケースが存在するというだけで、そのすべてを要求してはいけません。
出力
最初に判定を示してください。各分類の根拠となる証拠だけを残し、繰り返されるテストの概要や一般的なテストのアドバイスは省いてください。
保護が失われる、または保守コストが増える仕組みごとに、繰り返し見られる弱点をまとめ、代表的な例と影響を受けるテストグループを示してください。契約や証拠が異なる場合は、分類を分けたままにしてください。構文が共通していることは、指摘をまとめる理由にはなりません。
情報を加えるセクションだけを使用してください。
- 判定:強い(重大な欠落なし)、十分(現時点で対応不要の欠落がある)、混在、テスト不足、実装依存、またはほぼノイズ。
- 保護されている内容:テストが現在カバーしている契約。
- 最大の問題:優先順位を付けた問題、例、および推奨事項。
- 維持/修正/削除/追加:具体的な分類。
- 最も価値の高い次の変更:信頼性を高める、最小限の変更。
テストが強い場合は、その旨を伝え、残る盲点を挙げてください。テストが何を保護しているかを判断するうえで、コンテキストの不足が妨げになる場合に限り、質問してください。
テストの編集
ユーザーから明示的に依頼された場合に限り、テストを編集してください。編集する際は、契約を保護するテストを維持し、弱いテストは観測可能な動作を検証する形に書き換え、冗長、誤解を招く、壊れやすい、または何の契約も保護しないテストを削除し、重要なリスクに対する焦点を絞った回帰テストを追加してください。利用できる場合は、最も関連性の高いテストコマンドを実行してください。そうでない場合は、次善の確認方法を説明してください。
期待値を変更するのは、要件が変更された場合、または既存のテストが誤りだと示された場合に限ります。インターフェースやセットアップを変更する際も、保護対象のケースを維持してください。テストを修正した結果、プロダクションコードの不具合が明らかになった場合は、テストを失敗したままにして報告してください。テストの整理は、プロダクションコードの修正や期待値の緩和を許可するものではありません。成功、失敗、スキップ、および実行できなかった結果は、それぞれ分けて報告してください。
制約
- テストが存在するという理由で、そのテストを擁護しないでください。
- すべての行やヘルパーにテストを要求したり、ユニットテストですべてをモックする必要があると扱ったりしないでください。