🔍검색

ホーム › ガイド

ミューテーションテストの偽のkill:ベースライン・ファイルアクセス・kill理由

公開日 2026-10-27

ミューテーションテストは、コードを意図的に変更し(<を<=に、return xをreturn Noneに)、テストがそれに気づくかを確かめる手法です。「killed」と判定されたミュータントは、テストが失敗したことを意味します。しかし、テストはミューテーションとは無関係な理由でも失敗します。そうなると、ミューテーションスコアは実際のテストの実力より良く見えてしまいます。このガイドでは、こうした偽のkill(false kill)を見つける3つのチェックを紹介します。

偽のkillが起きる理由

原因見えるもの
ミューテーションの前から、スイートが失敗していた、または不安定だった無関係な同じエラーによるkillが多数
テストが変更後のコピーではなく、元のファイルをインポートしているkillがタイムアウトか環境エラーによるものだけ
遅いマシンによるタイムアウト実行時間の長いテストにkillが集中
実行間で共有される状態(一時ファイル、キャッシュ、ポート)同じミュータントを再実行すると、killの結果が変わる

タイムアウトはスコアに影響します。Strykerでは、detected = killed + timeout、mutation score = detected / valid × 100です。タイムアウトが多発するマシンでは、スコアが水増しされます。出典:Stryker mutant states and metrics、2026-10-19確認。

チェック1 — まっさらなコピーでベースラインを取る

  1. ミューテーションツールが使うのとまったく同じ条件(同じサンドボックス、同じ環境変数)で、プロジェクトを新しいディレクトリにコピーします。
  2. そこで、ミューテーションをかけずに、テストスイート全体を3回実行します。
  3. 3回とも通らなければなりません。ここでの失敗は既存の失敗で、後で偽のkillとして現れます。先に修正するか、隔離してください。
cp -r project /tmp/mt-baseline && cd /tmp/mt-baseline
for i in 1 2 3; do pytest -q -p no:cacheprovider || echo "BASELINE FAIL $i"; done

チェック2 — テストが変更後のファイルを読んだことを証明する

テストが変更後のファイルを一度も読み込まないなら、そのミュータントをkillできたはずがありません。ミュータントごとの実行中に、ファイルアクセスを記録します。Pythonなら、audit hookで十分です。

# conftest.py
import sys, os
TARGET = os.environ.get("MUT_TARGET")  # path of the mutated file
def hook(event, args):
    if event == "open" and TARGET and str(args[0]).endswith(TARGET):
        open("/tmp/mut_touched", "a").write("1")
sys.addaudithook(hook)

各ミュータントの実行では、古いバイトコードを削除し(コピー内の__pycache__を消します)、ソースファイルが実際に読まれるようにします。ルールは次のとおりです。対象ファイルが一度も開かれなかったkillはsuspect(疑わしい)とマークして再実行します。他のスタックでは、strace -e trace=openat(Linux)やテストランナーのカバレッジデータが同じ役割を果たします。

チェック3 — killの理由の分布を見る

  1. killされたミュータントごとに、実行が失敗した理由を保存します。アサーションエラー、その他の例外、タイムアウト、クラッシュ、収集/インポートエラーです。
  2. 簡単な集計表を作ります。
理由健全なパターン危険信号
アサーション失敗大半のkill—
その他の例外いくらか多数のミュータントで同一のメッセージ
タイムアウト少数(無限ループのミュータント)割合が大きい。遅いマシンで増える
インポート/収集エラーほぼなし無視できない割合があれば、失敗しているのはテストではなくハーネス

まとめ

FAQ

タイムアウトを延ばすべきですか?
ベースラインから決めてください。通常のスイートの実行時間を測り、その何倍かを許容します。短すぎると偽のkillが生まれ、長すぎると実行が遅くなります。
コンパイルエラーはカウントされますか?
Strykerでは、コンパイルエラーと実行時エラーは「invalid」なミュータントとなり、スコアには含まれません。

出典

関連(韓国語): 開発知識まとめ(韓国語)(개발 지식 모음)

🌐 English · Español · Bahasa Indonesia · 日本語 · ไทย · Tiếng Việt · 中文

📤 공유