mcpField
M
mutation-testing

mutation-testing

github.com/dmokaテスト・品質2187 回インストール5 週間前に更新
リポジトリ

mutation-testing について

mutation-testingは、テストが小さなコード上の欠陥を検出できるか評価するエージェント向けスキルです。安定したベースラインの確認から、対象を絞った変異テスト、残存変異の分析、制約を含む結果報告までを案内します。

主な機能

  1. 01テストのベースラインと安定性を確認
  2. 02スタックに応じたツールを選択・設定
  3. 03単一モジュールを対象に変異テストを実行
  4. 04残存変異を説明しリスク順に整理
  5. 05業務上の結果を検証するテストを追加
  6. 06スコアの限界と承認事項を報告

活用シーン

  1. 01ユニットテストの論理エラー検出力を評価
  2. 02金額や権限コードのテスト不足を優先確認
  3. 03設定を弱めずに残存変異を調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dmoka/skills --skill mutation-testing

インストール後、Claude Code で/mutation-testingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
gotchas.md
judge.md
tools.md

詳細

ミューテーションテスト

カバレッジからは、コードが実行されたことが分かります。ミューテーションテストからは、そのコードに誤りがあったときにテストが気づくかどうかが分かります。ツールは小さなバグを1つずつ埋め込み(ミュータント:>= を > にする、+ を - にする、条件を削除するなど)、テストスイートを再実行して判定を記録します。テストが失敗すれば、そのミュータントはキルされます。テストスイートがグリーンのままなら、そのバグは見逃されています。生き残ったミュータントはすべて、テストスイートがついている嘘です。

参照ファイルはこのファイルと同じ場所にあります。ディスク上のファイルではなく HTTP 経由でこれを取得した場合は、tools.md、gotchas.md、judge.md を https://raw.githubusercontent.com/dmoka/skills/main/skills/mutation-testing/references/ から取得してください。

要約ではなく、未加工のテキストを取得してください。 多くのエージェントには、ページを要約モデルに通すフェッチツールがあります。そのツールはこのファイルを言い換え、番号付きの手順を削除し、これからコピーする設定スニペットを台無しにします。フェッチ結果が以下の文字どおりの Markdown ではなく文章になっている場合は、curl -sSL <url> で再取得し、その内容をもとに作業してください。

ループ

  1. ベースライン。 テストスイート全体を 2 回実行します。失敗:BLOCKED と報告します。ミューテーションツールは失敗するベースラインを拒否します。2 回の実行で判定が変わる場合は、不安定なテストです。そのテストに続くミュータントの判定はすべてノイズです。実際の不具合を確認でき、その修正がテストに含まれている場合を除き、そのテストを隔離します(スキップし、理由と人間が判断すべき内容をコメントに記載します)。テストを「修正」するために仕様をでっち上げてはいけません。テストが e2e/CI 専用のものしかない場合、またはローカルでスイートの実行に数分以上かかる場合も、BLOCKED と報告します。ミューテーションテストには高速なローカル単体テストスイートが必要であり、その不足が調査結果です。モノレポでは、対象モジュールを所有するパッケージ内で作業します。数値を得るために失敗するテストを除外してはいけません。
  2. スタックに合ったツールを選びます(下の表を参照)。プロジェクト内にインストールし、references/tools.md に従って設定します。ツールの対話型初期化ウィザードは実行せず、設定ファイルを自分で作成します。グローバルインストールを行う前に確認してください。
  3. 最初の実行範囲を 1 つのモジュールに絞ります。ユーザーが指定した最もビジネス上重要なファイル、またはサイレントバグの損失が最も大きいファイル(金額計算、権限、データ書き込みなど)を選びます。指定がなければ、自分で選びます。通常、README やパッケージ構成からビジネスロジックの所在が分かり、サイレントバグの損失が最も大きいロジックのファイルが最初に調べる対象です。選んだファイルとその理由を伝えます。実際のコードベースでリポジトリ全体を最初に実行すると何時間もかかり、途中で失敗することもよくあります。1 つのモジュールに絞れば数分で完了し、効果を実証できます。最初の実行が成功してから、範囲を広げます。1 つのモジュールでコードベース全体をカバーできるほど小さなプロジェクトでは、その旨を伝えて先に進みます。この手順を満たすために、無理に範囲を狭めてはいけません。
  4. 実行時はコンソール出力のみを使用し、実行結果のレポートファイルがディスクに残らないようにします(ツールごとのフラグはreferences/tools.mdを参照)。コンソールから生き残ったミュータントを確認します。
  5. 生き残ったミュータントをそれぞれ、テスターでない人にも分かる 1 文で説明します。ミュータントが何を変更し、どの具体的な入力で誤った出力が許されるのかを示します。例:「上限の 2000 セントが削除され、1,000 ユーロの注文で上限の 20 ユーロではなく 30 ユーロの手数料が発生します。」数値は残します。「高額注文で過剰請求される」では、読者が確認すべき内容が分かりません。
  6. 影響範囲の大きさで生き残ったミュータントを順位付けします。金銭やデータ損失につながる経路を最初にし、次に境界条件、最後にログや書式設定を扱います。
  7. 殺すか、主張を立てます。 殺せるミュータントごとに、ビジネス上の結果を検証するテストを作成し、ツールを再実行して殺せたことを確認します。殺せないミュータントを、自分で同等だと判定してはいけません。ゲートを通したいエージェントは、殺せるミュータントを殺せないと判断する可能性が最も高いためです。代わりに、ミュータントと元のコードを、単独で、またはコンテキスト内で区別できる入力が存在しない理由を主張として記述します(references/gotchas.md)。
  8. 主張ごとに、新しいエージェントで判定します。主張 1 件につき判定エージェントを 1 つ使います。Claude Code のサブエージェント(Agent ツール)、別のハーネスのサブエージェントまたは委任ツールを使います。それ以外の場合は新しいセッションを使い、自分自身のコンテキストで判定してはいけません。references/judge.mdをそのまま渡し、元のコード行とその関数、ミュータント、主張、テストコマンドだけを添えます。すべての判定エージェントを同時に開始し、すべての判定が終わるまで待ちます。判定エージェントが殺せる入力を見つけた場合、主張は却下です。テストを残し、ツールを再実行して殺せたことを確認します。指定された範囲内で見つからなかった場合は、主張を認め、「判定済み:識別可能な入力は見つからず」と記載します。
  9. 除外する前に一度だけ確認します。 判定メモとともに、認められた主張をすべて列挙し、除外を承認するかユーザーに一度だけ確認します。承認を得てから、各行に理由を記したツールの除外コメントを追加します(構文はreferences/tools.mdを参照)。承認なしに除外を記述してはいけません。確認できる相手がいない場合(非対話型の実行、CI など)は、除外コメントを記述せず、認められた主張を未解決の判断事項として報告し、ゲートは失敗のままにします。
  10. 結果を先に報告し、200 語以内にまとめます。
    • 1 行で、ツール名とスコアに続けて「N 件を殺し、M 件は承認が必要」と記載します。
    • 生き残ったミュータントごとに 1 行を設けた表を作成します。列には、ミュータント(file:line、元のコード → ミュータント)、変更内容(手順 5 の具体的な入力と誤った出力)、殺害済み(新しいテスト名)または承認が必要(判定結果を短く記載)を含めます。各セルは短い句にします。
    • 手順 9 の承認を求める質問を 1~2 文で記載します。回答できる人がいない場合は「未解決の判断事項」と記載します。
    • スコアでは検出できない内容(下記)を 1 文で記載します。追加または変更したファイルと、ディスクに残したツール出力があれば、その内容を 1 文で記載します。 それ以外は不要です。セットアップの経緯やベースラインの説明は、ブロックされた場合や不安定だった場合を除き、記載しないでください。判定ツールが試した入力の一覧も不要です。

スタック別のツール

スタックツール
JavaScript / TypeScriptStrykerJS
C# / .NETStryker.NET
Java / KotlinPitest
Pythonmutmut
Rustcargo-mutants
PHPInfection
Go、Ruby、その他references/tools.md を参照してください

各ツールのセットアップ、設定、対象を絞った実行コマンドについては、references/tools.md を参照してください。

厳守事項

  • スコアを上げるために設定を変更してはいけません。 スコアは結果を伝えるものです。 ファイルの除外、タイムアウトの延長、ミューテーターの無効化、テストを通すためのテストファイルのスキップは、常に禁じられている唯一の行為です。
  • ミューテーションを検出するテストは、ミュータントの動作ではなく、ビジネス上の結果を検証します。 そのテストがユーザーにとって何を守るのかを一文で説明できないなら、数値を動かすためだけのテストを書いています。そのテストは削除してください。
  • 重要な処理経路に生き残ったミュータントが1つでもあれば、スコアより重大です。 決済コードにミュータントが生き残っていれば、スコアが95%でも不合格です。100%を追い求めないでください。同等ミュータントがあるため達成できず、100%を要求するとループが収束しなくなります。
  • 実行対象は実行ごとに広げてもかまいませんが、狭めてはいけません。 生き残った難しいミュータントを対象外にする再スコープは、スコアの不正操作です。ツールが永続的な設定ファイルで対象範囲を絞っている場合は、作業を終える際に対象範囲を広げるか、その設定を削除してください。絞ったまま残すと、次の担当者に除外設定を引き継ぐことになります。
  • 本番ソースは読み取り専用です。 テスト、ビルドファイル、ツール設定は追加・変更できます。レポートには、変更したファイルがすべて記載されます。唯一許可されるソースの変更は、ステップ9でユーザーが承認した除外コメントです。ミュータントを検出するためにソースの変更が必要な場合は、編集せず、発見事項として報告してください。Rust の #[cfg(test)] mod tests や Python の doctest のように、ユニットテストがソースファイル内にある言語では、そのファイルにテストを追加してもかまいません。ただし、それより上にあるコードには決して触れず、レポートでソースファイルを編集したこととその理由を明記してください。
  • 1回のシェル呼び出しにつき、コマンドは1つだけです。 for ループ、&& の連結、; による連続実行、tail へのパイプは使わないでください。コマンドを許可リストで制限するハーネスでは、複合コマンドの実行ごとに許可を求められ、非対話型の実行は拒否されます。ベースラインは2回、別々の呼び出しで実行してください。長い出力はツール自身のサマリーを読んでください。
  • リポジトリの外に出ないでください。 一時スクリプト、ダウンロードしたスキルのコピー、同等性チェックは、プロジェクト内の無視対象の一時領域か、エージェントのワークスペースに置いてください。兄弟ディレクトリやシステムの一時ディレクトリには置かないでください。テストの再現性を高めるために、リポジトリ外のマシン状態を削除または書き換えてはいけません。テストがそのような状態に依存している場合は、発見事項として報告してください。

スコアでは見えないこと

ミューテーションテストでは、記述されたコードに対して、用意されたテストを評価します。実装されていないビジネスルールからはミュータントが生成されないため、機能が完全に欠けていてもスコアが100%になることがあります。スコアを報告するときは、どのリスクが対象外なのかを明記してください。未実装コードの見落としやその他の制限については、references/gotchas.md を参照してください。

スコアの信頼性は、ツールのミューテーターの性能に左右されます。 これらのツールは同等ではありません。境界を1つずつ書き換える演算子を使うものもあれば、関数本体全体を置き換えるものもあります。弱いミューテーターセットで得た100%の上に、テストされていない1つずつの差異が隠れていることもあります。スコアを報告する際は、ツール名と既知の見落としやすい点も併記し、パーセンテージだけを示さないでください。ツールごとの制限については、references/gotchas.md を参照してください。

普遍的に適切なスコアはありません。変更したコードを基準に判定してください。そのコードのすべてのミュータントが検出されるか、ユーザーの承認を得て除外されている必要があります。

完了の条件

  • 対象コードにおいて、金額、権限、保存済みレコードを変更できるミュータントが残っていないこと。
  • 残っているサバイバーはすべて、フレッシュな判定者がキルできなかったと判断した書面上の主張であること。除外コメントはすべて判定され、ユーザーが承認していること。誰も承認していない主張は、除外せず未決事項として報告すること。
  • すべてのサバイバーについて、テスト担当者でなくても理解できる一文で説明されていること。
  • 追加したテストはすべて、ビジネス上の結果を検証し、再実行時に該当するミュータントをキルすることが確認されていること。
  • リポジトリがクリーンであること。ツールの出力ディレクトリは削除するか、gitignore に追加すること。設定に記述したスコープは拡大するか削除すること。追加または変更したファイルをすべてレポートに記載すること。git status ではなく、ファイルシステム上で確認すること。ツールによっては出力ディレクトリに独自の .gitignore を書き込むため、数百メガバイトが蓄積していても git status ではクリーンと報告されることがあります。残すことにした出力と、その保存場所を明記してください。

説明のないサバイバーが残っている高スコアは、完了ではありません。ユーザーが受け入れることを選んだ、説明済みで優先順位付けされたサバイバーが3つある完成済みレポートこそが、完了です。

最終確認日:2026-10-05、Claude Code(claude-opus-5-5、ヘッドレス、TicketBay での StrykerJS:判定、承認、レポートの各ステップ)。ツールのセットアップ最終確認日:2026-09-02(9つのスタックでライブテスト)。

コメント