Communityライティング&編集github.com

test-suite-doctor

エージェントスキル+スタンドアロンCLI:肥大化したVitest/Jestテストスイートを監査・最小化・修復します。テストごとのカバレッジ測定、貪欲最小化、AI生成スロップ検出、ミューテーションスコア検証を備えています。

test-suite-doctor とは?

test-suite-doctor は、数千件に及ぶAI生成された低品質テストを含む肥大化したテストスイートを、測定されたカバレッジを保持しながら効率的に縮小するためのエージェントスキル兼CLIツールです。対象プラットフォームは Vitest と Jest で、Node.js 22 以降が必要です。まず `collect` で全テストファイルのカバレッジと実行時間を計測し、次に `minimize` が貪欲アルゴリズムでカバレッジフロアを満たす最小限のテストセット(例:200件)を選択します。`verify` コマンドでカバレッジ維持を確認し、必要に応じて `@stryker-mutator/core` によるミューテーションテストも実施できます。ワークフローは「計測→最小化→レビュー→再生成→検証」の5ステップで、削除候補は人間がレビューし、契約テストや回帰テストは強制保持されるため、安全性と効率性を両立します。

対応~Claude Code~Codex CLI~Cursor
npx skills add JoseAntonioNuevo/test-suite-doctor

Installed? Explore more ライティング&編集 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

test-suite-doctor は何をしますか?

肥大化したテストスイート(例:2000件以上のテスト、その多くがAI生成のスロップ)を、実際のカバレッジを測定して保持しながら、小さく高品質なスイートに縮小します。

ハードルール

  1. 意見より指標。 collect と minimize で計画を作成する前に、テスト削除を提案してはいけません。テストコードを読んで「役に立たない」と判断しても証拠にはなりません。些細に見えるテストが唯一のブランチカバレッジになることもあります。
  2. 計画は提案であり、最終判断ではない。 カバレッジはAPIコントラクト、文書化された回帰テスト、プロパティ不変条件を考慮できません。削除候補はすべて、削除前にレビュー(ステップ3)を受ける必要があります。
  3. ブランチで作業する。 テスト削除前に、ワーキングツリーがクリーンであることを確認し、ブランチ(例:test-doctor/minimize)を作成します。ダーティツリーまたはデフォルトブランチでテストを削除してはいけません。
  4. 検証するか、元に戻す。 verify が終了コード0を返すまで作業は完了しません。失敗した場合は、報告されたギャップに対するテストを再生成して再検証するか、削除したテストを復元します。

要件確認(最初に行うこと)

  • Node.js 22 以上、およびローカルインストールされた Vitest または Jest を使用する package.json が必要です(node <skill-root>/dist/cli.mjs collect --help)。
  • カバレッジプロバイダがインストールされている必要があります(Vitest: @vitest/coverage-v8;Jestには組み込み済み)。不足している場合は、開発依存関係としてインストールするよう提案します。
  • ミューテーション検証には、対象リポジトリで @stryker-mutator/core が設定されている必要があります。これはオプトインであり、促されずにインストールしてはいけません。
  • 開始前にテストスイートがグリーン(成功)している必要があります。ベースライン実行で障害が報告された場合は、ユーザーに通知し、最小化前にどのように対処するか合意を得てください(失敗するテストは信頼できないカバレッジを提供します)。

以下のすべてのコマンドは対象リポジトリのルートから実行します。$SKILL はこのスキルのディレクトリです。生成物は .test-doctor/ に配置されます(.gitignore への追加を推奨)。

ワークフロー

1. 計測(スクリプト — 常に最初)

node "$SKILL/dist/cli.mjs" collect --cwd .

テストランナーを検出し、全スイートを1回実行してカバレッジベースラインを取得した後、各テストファイルを個別に実行してカバーした行・ブランチと実行時間を記録します。.test-doctor/report.json を書き出します。

  • デフォルトの粒度はテストファイル単位です(テスト単位の分離は正確ですが、すべてのテストを個別に実行するため、小規模または既に縮小されたスイート、または --filter でスコープ指定した場合のみ --granularity test を提供してください)。
  • 2000件のテストスイートでは時間がかかるため、バックグラウンドで実行し、進捗を報告します。レポート内の collectionErrors を真剣に受け止めてください。これらのエラーはデフォルトで最小化をブロックします。ユーザーが明示的に --keep-unmeasured を選択した場合、影響を受けるすべてのユニットは強制的に保持され、計画は信頼できないとマークされます。
  • --filter は意図的にスコープされたベースラインを作成します。収集、最小化、検証は一致するテストファイルのみに適用されます。すべての推奨事項でそのスコープを明示してください。これはリポジトリ全体の保証ではありません。

2. 最小化(スクリプト)

node "$SKILL/dist/cli.mjs" minimize --coverage-floor 0.97 --target-count 200

貪欲重み付き和選択:カバレッジフロアを満たすまで、実行時間1ミリ秒あたりに新しくカバーする行・ブランチが最も多いユニットを繰り返し保持します。.test-doctor/plan.json と、保持・削除された各ユニットの正当性を記した人間が読める .test-doctor/plan.md を書き出します。

  • ユーザーが指定しない場合はしきい値を尋ねてください。デフォルトは行カバレッジフロア0.97、ブランチフロアなし、ターゲット数なしです。--help ですべての調整項目を表示できます。
  • 既知の契約テストや回帰テストは事前に強制保持します。--keep 'contract' --keep 'regression'(ユニットIDに対する正規表現)。
  • 計画の warnings 配列に注意してください。例えば、フロアに到達できない、ターゲット数より多くのユニットが必要になるなどの警告です。これらをユーザーにそのまま伝えてください。

3. レビュー(判断 — あなたの作業)

references/slop-patterns.md を読み、plan.md の削除リストをレビューします。

  • カバレッジでは見えない振る舞いを検証するテストを救出します。公開APIコントラクト、課題/バグIDを参照する回帰テスト、コンシューマーが依存するエラーメッセージの文言、プロパティ/不変条件チェックなどです。計画を手動編集する代わりに、追加の --keep パターンで minimize を再実行します。
  • 残りが安全な削除であることを確認し、スロップパターンごとに分類して、各テストがなぜ削除されるのかをユーザーに示します(パターンファイルにカタログがあります)。

次に、references/quality-rules.md に照らして保持リストをレビューします。怪しい保持テスト(モックのモック、トートロジー、空のスナップショットなど)はその場で書き換えます。カバレッジは獲得しますが、きれいに獲得すべきです。

このレビューが完了した後にのみ、ブランチ上で削除されたテストファイル/ケースを削除します。ユニットがすべて削除された場合はファイル全体を削除し、ファイル内の一部のテストのみが削除される場合はファイルを編集します(テスト粒度)。

4. 再生成(判断 — あなたの作業)

verify を一度実行し(失敗する可能性があります)、カバレッジギャップレポートを取得し、verify がリストする最も影響の大きいソースファイルに対して新しいテストを記述します。references/quality-rules.md に従います:AAA構造、振る舞い駆動の名前、テストごとに1つの振る舞い、モックは外部境界のみ。3つの浅いテストよりも、実際のユーザーに見える振る舞いをカバーする1つの強力なテストを優先します。

5. 検証(スクリプト — 完了のゲート)

node "$SKILL/dist/cli.mjs" verify --coverage-floor 0.97
# オプション、クリティカルモジュールのみ(低速):
node "$SKILL/dist/cli.mjs" verify --mutation --mutate "src/billing/**/*.ts" --mutation-floor 80

スイートを再実行し、グリーンであること、およびベースラインに対する行保持率がフロアを満たすことを要求します。終了コード0 = 完了、1 = 修正して再実行(テスト再生成または削除の復元)、2 = 環境の問題、停止して報告。ミューテーションテストはモジュールごとのオプトインであり、低速のため、ユーザーがクリティカルと呼ぶモジュールに対してのみ提供します。

バージョン2ではカバーされたソース、ランナー設定、ロックファイル、ランナー、カバレッジプロバイダをベースラインに記録します。verify が来歴のずれを報告した場合は、新しいベースラインを収集します。--allow-provenance-drift は明示的なユーザー同意がある場合のみ使用し、結果の判定は信頼できないと報告します。レガシー v1 ベースラインも同様に、明示的な --allow-legacy-baseline エスケープハッチが必要です。

報告

ユーザーに要約します:元のユニット数 → 後のユニット数、行/ブランチ保持率、実行時間 前 → 後、見つかったスロップパターン(件数付き)、削除リストから救出したテストとその理由、再生成したテスト、最終的な verify の判定。完全な監査証跡として plan.md へのパスを含めます。

失敗モード

  • ランナーが検出されない/曖昧 → CLI は終了コード2でガイダンスを表示します。--runner または --cwd を指定します(モノレポ:パッケージごとに実行)。
  • 収集が不完全 → 個別の失敗を修正します。単に計画を通すためにフィルタリングしてはいけません。フィルタは宣言されたベースラインスコープを変更します。--keep-unmeasured は保守的なエスケープハッチです。
  • 再生成後も verify が失敗し続ける → 約3回の試行でループを停止し、残ったギャップをファイルごとに提示し、ユーザーにフロアを下げるかテストを維持するかを決定させます。
  • スイートが開始前にレッドだった → 無関係な失敗を黙って「修正」せず、報告し、最初にスコープについて合意します。

関連スキル