突然変異テストとは何ですか? (例)
⚡ スマートサマリー
ミューテーションテストでは、ソースコードに意図的に小さな欠陥を導入し、既存のテストスイートを欠陥のあるすべてのバージョンに対して実行し、それらのテストが変更を検出するのに十分な強度を持っているかどうかを測定します。
突然変異テストとは何ですか?
突然変異テスト ミューテーションテストとは、ソースコードの特定の記述を変更(ミューテーション)して、テストケースがソースコードのエラーを検出できるかどうかを確認するソフトウェアテストの一種です。ミューテーションテストの目的は、テストケースの堅牢性を確保し、変更されたソースコードに対してテストケースが失敗するようにすることです。
ミューテーションプログラムに加えられる変更は、プログラム全体の目的に影響を与えないように、極めて小さく抑えなければなりません。ミューテーションテストは、意図的にプログラムに欠陥を作り出すため、欠陥ベースのテスト戦略とも呼ばれます。これは、 ホワイト Box テスト 主に適用されるのは 単体テスト.
突然変異テストは、1971 年にリチャード・リプトンによる学生論文で提案され、1978 年にデミロ、リプトン、セイワードによる論文「テストデータ選択のヒント」で形式化されました。当時の計算コストのために勢いを失いましたが、その後、次のような言語で再び勢いを取り戻しました。 Java、C#、 Python, JavaスクリプトとXML。
ミューテーションテストを実行するにはどうすればよいですか?
変異テスト(変異解析とも呼ばれる)を実行する手順は以下のとおりです。
ステップ1: プログラムのソースコードに欠陥を導入するために、ミュータントと呼ばれる多数のバージョンを作成します。各ミュータントには単一の欠陥が含まれている必要があり、テストケースの有効性を実証するために、ミュータントバージョンを失敗させることが目標です。
ステップ2: テストケースは元のプログラムと変異プログラムの両方に適用されます。 テストケース は適切であるはずであり、プログラム内の障害を検出するために調整されています。
ステップ3: 元のプログラムと変異プログラムの結果を比較してください。
ステップ4: 元のプログラムと変異プログラムが異なる出力を生成する場合、変異プログラムはテストケースによって排除されます。したがって、このテストケースは元のプログラムと変異プログラム間の変更を検出するのに十分です。
ステップ5: 元のプログラムと変異プログラムが同じ出力を生成する場合、変異プログラムは生存したままとなる。このような場合、すべての変異プログラムを排除できる、より効果的なテストケースを作成する必要がある。
下の図 trac元のプログラムから突然変異体の生成、そして殺されるか生き残るかの判決まで、同じ5つのステップを踏む。
突然変異プログラムを作成するにはどうすればよいですか?
変異とは、プログラム文に加えられる単一の構文変更に他ならない。各変異プログラムは、元のプログラムと正確に1つの変異だけが異なるべきである。
| オリジナルプログラム | ミュータント プログラム |
| (x>y) の場合 「こんにちは」を印刷する 他 「こんにちは」を印刷する |
もし(x) 「こんにちは」を印刷する 他 「こんにちは」を印刷する |
上記のペアでは比較演算子のみが変更されていますが、x が y より大きいテストケースでは、「Hello」ではなく「Hi」と表示されます。この図は、1 つの構文変更を示しています。
ミュータント プログラムでは何を変更する必要がありますか?
変異プログラムを生成するために使用できる手法はいくつかあります。以下の3つのファミリーは、ツールに付属するほとんどの変異演算子を網羅しています。
| Operand置換演算子 | 式変更演算子 | ステートメント変更演算子 |
| オペランドを別のオペランド(xをyに、またはyをxに)または定数値に置き換えます。 | プログラム文内の演算子を置換するか、新しい演算子を挿入します。 | プログラムステートメントは、突然変異したプログラムを作成するために変更されます。 |
| 例: If(x>y) x と y の値を置き換えます If(5>y) x を定数 5 に置き換えます |
例: If(x==y) == を >= に置き換えると、ミュータントプログラムは次のようになります。 If(x>=y) とステートメントに ++ を挿入する If(x==++y) |
例: if-else ステートメントの else 部分を削除する プログラムの動作を確認するために、if-else文全体を削除してください。 |
変異演算子の例をいくつか挙げます。
- GOTOラベルの交換
- return ステートメントの置換
- ステートメントの削除
- 単項演算子の挿入(例:- および ++)
- 論理コネクタの交換
- 同等の配列名の置換
- if-else文のelse部分を削除する
- オペレーターの追加または置換
- データ変更によるステートメントの置換
- 変数のデータ変更
- プログラム内のデータ型の変更
Opera境界条件に接触する変異体は最も頻繁に生き残るため、突然変異の結果はしばしばギャップを指摘する。 境界値解析.
突然変異テストの種類
In ソフトウエアエンジニアリングミューテーションテストは、基本的にステートメントミューテーション、値ミューテーション、および決定ミューテーションの3種類に分類されます。
- ステートメントの突然変異 ステートメントが切り取られたり、貼り付けられたり、削除されたりするため、結果としてコードの一部行が削除される可能性があります。
- 値の突然変異 – ループの境界や閾値を変更するなど、主要なパラメータや定数の値が変更されます。
- 決定突然変異 – 制御文が変更されます。例えば、反転します。ping 関係演算子、または条件の否定。
ツールは演算子をこれら 3 つの見出しの下にグループ化するため、生存する変異体を生成したファミリーは、どのタイプのアサーションが欠落しているかをテスターに伝えます。生存する決定変異体は通常、テストされていないブランチを示し、それは以下と重複します。 ループテスト.
突然変異テストの自動化
ミューテーションテストは手動で実行すると非常に時間と手間がかかるため、自動化ツールを使用することをお勧めします。自動化ツールはコスト削減にもつながります。ミューテーションツールは、ミュータントをコンパイルし、実行スケジュールを設定し、失敗したテストごとにどのミュータントが停止されたかを記録し、スコアを報告します。
利用可能なツール一覧:
- ストライカー — オープンソースの変異テストフレームワークで、 Javaスクリプトと TypeScript (StrykerJS)、C#および.NET (Stryker.NET)、Scala (Stryker4s)。
- PITPITest とも表記される、突然変異検査システム Java そして、コンパイルされたバイトコードを変更し、MavenにプラグインするJVMと Gradle 一緒に構築する JUnit.
どちらもビルドステップとして実行されるため、同じ場所に属する 継続的インテグレーション パイプラインは残りの部分と同様に 自動化テスト 上。
突然変異スコア
突然変異スコアは、全突然変異体数に対する、死滅した突然変異体数の割合として定義される。
突然変異スコア = (殺された突然変異体 / 突然変異体の総数) * 100
以下に、ほとんどのツールが表示する形式で数式を示します。
テストケースは、スコアが100パーセントに達したときに変異が適切であると説明されます。実際には、分母は除外する必要があります。 同等の変異体 ―構文が変更されても元のものと全く同じように動作する変異体。そのため、どのテストでもそれらを排除することはできません。したがって、ツールは排除された変異体の数を、排除された変異体と生存している非同等の変異体の合計数で割った値を報告し、同等の変異体についてはテスターがフラグを立てるようにします。
実験結果から、突然変異テストはテストケースの妥当性を評価する効果的な方法であることが示されている。主な欠点は、突然変異体を生成し、それぞれの突然変異体に対してすべてのテストケースを実行するコストが高いことである。
突然変異検査 vs Code カバレッジ
ハイ テストカバレッジ これは強力なテストを証明するものではありません。行カバレッジと分岐カバレッジは、どのステートメントが実行されたかを記録するだけで、その後に何かが検証されたかどうかは記録しないため、メソッドを呼び出して何もアサートしないテストでもカバレッジされたとみなされます。ミューテーションテストはこのギャップを埋めます。なぜなら、ミュータントは実際にアサートが失敗した場合にのみ停止するからです。
| 側面 | Code カバレッジ | 変異スコア |
| 測定対象 | テストはどの行または分岐を実行したか | テストで検出された注入された欠陥はどれだったのか |
| 主張に敏感 | いいえ、アサーションがゼロのテストでもカバレッジは向上します | はい、どの主張も失敗しないときに突然変異体が生き残ります |
| ランニングの費用 | 計測機器を用いたテストラン1回 | 生き残った変異体1体につき1回のテスト実行、今のところは遅い |
| 典型的な使用 | コミットごとにクイックゲート | 重要モジュールに対するより詳細な定期点検 |
| 故障モード | 100%カバー、ただし実際の検証なし | 決して殺されない同等の突然変異体 |
この2つの指標は相互補完的です。カバレッジは到達しなかったコードを示し、ミューテーションスコアは到達したもののチェックされなかったコードを示します。どちらも同じ情報を提供します。 欠陥管理プロセス以下のような対策と併せて 欠陥密度.
突然変異テストの利点
変異テストの利点は次のとおりです。
- これは、ソースプログラムの高い網羅率を達成するための強力な手法である。
- テストスイート自体をテストするが、他のテストスイートはテストスイート自体をテストしない。 ソフトウェアテスト技術 直接行います。
- ミューテーションテストは、ソフトウェア開発者に優れたレベルのエラー検出機能を提供する。
- この手法はソースコード内の曖昧さを明らかにし、通常の実行では決して検出できない欠陥を暴く能力を持っている。
- 生き残った変異体は対処可能だ。それぞれが、ソフトウェアスイートが見逃した特定の行と特定の変更点を指摘している。
- 顧客はこのテストによって、より信頼性が高く安定したシステムを利用できるようになるというメリットを享受できます。
突然変異テストの欠点
一方、突然変異検査には以下のような欠点があります。
- 変異テストは、多数の変異プログラムを生成してコンパイルする必要があるため、非常にコストと時間がかかります。
- 時間がかかるため、このテストは自動化ツールなしでは実施できないと言っても過言ではないでしょう。
- 各変異体は、元のプログラムと同じ数のテストケースによって実行されるため、多数の変異体を用いてテストスイート全体を実行する必要がある。
- 同等の変異体は、いかなる検査でも死滅させることができず、真の生存者と区別するには通常、手作業による確認が必要となる。
- この方法はソースコードを変更するため、適用できません。 ブラック Box テスト.
突然変異検査はいつ行うべきか
上記のコストプロファイルから、ミューテーションテストはコードベース全体に対してコミットごとに実行されることは稀である。検出されない欠陥が大きな損失につながり、テスト対象のコードが小さく、かつ迅速に変化する可能性がある場合に、ミューテーションテストは費用対効果を発揮する。
- 安全性が重要なロジックまたは財務ロジック ―支払い計算、税務規則、承認チェックなど、誤った回答を黙って見過ごすことは、事故よりも深刻な事態を招く。
- 不審なほどカバー率の高いスイート ―カバー率がほぼ100%と表示されているにもかかわらず、欠陥が見過ごされている場合。
- レガシーコードのリファクタリング ―突然変異の結果は、既存の検査で回帰を検出できるかどうかを明らかにする。
- ライブラリと共有コンポーネント — 再利用された欠陥 コンポーネント 呼び出し元ごとに乗算されます。
- 練習中のチーム テスト駆動開発 ―このスコアは、最初に作成されたテストが実際に機能しているかどうかを確認するものです。
使い捨てのプロトタイプ、薄い接着線や分岐ロジックのない生成コード、あるいは低速なコードが支配的なスイートで実行する価値は通常ありません。 統合テスト すでに1回の通過に数時間かかる作業だ。
そのため、ほとんどのチームは変更されたファイルのみに実行範囲を限定し、重要なモジュールにしきい値を設定し、より広範囲の 回帰試験 スイートは残りの ソフトウェアテストのライフサイクル.



