ミューテーション解析

ミューテーション解析(ミューテーションテスト[※ 1]、ミューテーション法)はソフトウェアテストにおける、テストスイートの十分さを測定するための手法である。この手法では、テスト対象のプログラムの一部を機械的に書き換えることで、ミュータントと呼ばれる「人工的な誤りを含むプログラム」を生成する。テストスイートをミュータントに対して実行した結果と、元のプログラムに対して実行した結果が異なれば、テストスイートにはその誤りを発見するだけの鋭敏さが備わっていると考えられるだろう(テストスイートはミュータントをkillすると表現する)。機械的に大量にミュータントを生成したとき、そのうちテストスイートがkill出来るミュータントの割合を測定することで、テストスイートの「欠陥発見能力」の十分さを測定することが出来る。また、kill出来なかったミュータントをkillするように追加のテストケースを作成することで、開発者はテストスイートの欠陥発見能力を高めることが出来ると期待される。ミュータントを作成するためのプログラム書き換え方法をミューテーション操作と呼び、典型的なプログラムの誤り(演算子+(プラス)と-(マイナス)を逆にしてしまうなど)を模倣するものや、有意なテストケース生成を促すものなどが研究されている。ミューテーション解析によって既存のテストケース・テスト用入力データの十分さ・不十分さが測定でき、さらなるテストケースの作成・自動生成などに利用することが出来る。

ミューテーション解析の例

[編集]

ミューテーション解析は、プログラムを機械的に書き換えるミューテーション操作により、誤りを含んだプログラム(ミュータント)を作成する。テストスイートがその誤りを検出出来るかどうかが、テストスイートの十分さの指標として用いられる。

以下の様な単純なプログラムと、それに対するテスト用の入出力を例として考える。

if (a + b > 0) {     return true; } else {     return false; } 
テスト用データ
a b 出力
5 4 true
-5 -4 false

上記のプログラムに対して+(プラス)演算子を-(マイナス)演算子に置き換えるミューテーション操作を適用すると、以下の様なミュータントを得る。

if (a - b > 0) {     return true; } else {     return false; } 

ここで、上で示したテスト用データ1ではミュータントをkillすることが出来ない。従ってテストケースが不十分であるとされ、テストケースを追加するべきであるとわかる。この例では、例えば(a,b) = (-1, 2)のとき出力がtrueであることを確認するようなテストケースを追加すれば、ミュータントをkill出来る。

等価ミュータント

[編集]

等価ミュータントは、ミューテーション解析における未解決な問題の一つである。例えば、以下の様なコード片を考える。

int index = 0;  while () {     ;      index++;      if (index == 10) {         break;     } } 

==演算子を>=演算子に置き換えるミューテーション操作によって、以下の様なミュータントが生成される。

int index = 0;  while () {     ;      index++;      if (index >= 10) {         break;     } } 

しかし、このミュータントをkillするようなテストケースの生成は不可能である。生成されたミュータントは元のプログラムと常に同じように振る舞うためである。このようなミュータントを等価ミュータントと呼ぶ。

等価ミュータントの検出はミューテーション解析を実用に移すことを阻む大きな障害の一つである。等価ミュータントの判別を手動で行わなくてはならない場合、たとえ小さなプログラムが対象であってもそのコストは甚大なものになる。

注釈

[編集]
  1. ^ mutation analysisよりもmutation testingという単語が広く使われているが、ミューテーション解析はソフトウェアが想定通りに実装されていることを直接確かめるテスティングとは異なり、テスティングで利用されるテストケースの品質を評価するための手法である。従って、本稿ではミューテーション解析という用語を主に利用する。