PITestによる突然変異テスト
1概要
ソフトウェアテストとは、ソフトウェアアプリケーションの機能を評価するために使用される手法のことです。この記事では、http://pitestを使用して突然変異テストを実行する方法に特に興味を持って、
コードカバレッジ
や
突然変異テスト
など、ソフトウェアテスト業界で使用されるいくつかの測定基準について説明します。 .org/[
PITestライブラリ
]。
簡単にするために、このデモでは基本的な回文関数に基づいて説明します。回文は同じ前後方向を読み取る文字列です。
2 Mavenの依存関係
Mavenの依存関係の設定を見るとわかるように、JUnitを使ってテストを実行し、
PITest
ライブラリを使ってコードに
ミュータント
を導入します。心配しないでください。
link
をたどることで、いつでもMavenの中央リポジトリに対する最新の依存関係バージョンを調べることができます。
<dependency>
<groupId>org.pitest</groupId>
<artifactId>pitest-parent</artifactId>
<version>1.1.10</version>
<type>pom</type>
</dependency>
PITestライブラリを起動して実行するには、
pitest-maven
プラグインを
pom.xml
設定ファイルに含める必要があります。
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.1.10</version>
<configuration>
<targetClasses>
<param>com.baeldung.testing.mutation.** </param>
</targetClasses>
<targetTests>
<param>com.baeldung.mutation.test.** </param>
</targetTests>
</configuration>
</plugin>
3プロジェクト設定
Mavenの依存関係が設定されたので、次はこの説明のつかない回文関数を見てみましょう。
public boolean isPalindrome(String inputString) {
if (inputString.length() == 0) {
return true;
} else {
char firstChar = inputString.charAt(0);
char lastChar = inputString.charAt(inputString.length() - 1);
String mid = inputString.substring(1, inputString.length() - 1);
return (firstChar == lastChar) && isPalindrome(mid);
}
}
ここで必要なのは、私たちの実装が望みどおりに機能することを確認するための単純なJUnitテストです。
@Test
public void whenPalindrom__thenAccept() {
Palindrome palindromeTester = new Palindrome();
assertTrue(palindromeTester.isPalindrome("noon"));
}
今のところ、JUnitテストとしてテストケースを正常に実行する準備ができています。
次に、この記事では、PITestライブラリを使用して
コードとミューテーションカバレッジ
に焦点を当てます。
4コードカバレッジ
コードカバレッジは、自動テスト中に
実行パス
の何パーセントが実行されたかを測定するためにソフトウェア業界で広く使用されています。
Eclipse IDEで入手可能な
Eclemma
のようなツールを使用して、実行パスに基づいて有効なコードカバレッジを測定できます。
コードカバレッジを指定して
TestPalindrome
を実行すると、100%のカバレッジスコアを簡単に達成できます –
isPalindrome
は再帰的なので、空の入力長チェックがいずれにしてもカバーされることは明らかです。
残念なことに、100%のコードカバレッジスコアは、すべての行が少なくとも一度は実行されたことを意味するだけなので、コードカバレッジメトリクスはかなり
無効
になることがあります突然変異テストが実際に重要なのはなぜですか。
5変異カバレッジ
ミューテーションテストは、テストの妥当性
を改善し、コード内の欠陥を特定
するために使用されるテスト手法です。そのアイデアは、プロダクションコードを動的に変更してテストを失敗させることです。
良いテストは失敗するでしょう
コードの変更はそれぞれ
ミュータント
と呼ばれ、その結果、プログラムの変更されたバージョンが
ミュータント
と呼ばれます。
テストで失敗する可能性がある場合、その突然変異は「殺される」と言います。また、突然変異体がテストの動作に影響を与えないのであれば、突然変異体は
生き残った
と言います。
では、Mavenを使用してテストを実行しましょう。ゴールオプションを次のように設定します。
org.pitest:pitest-maven:mutationCoverage
。
HTML形式のレポートは
target/pit-test/YYYYMMDDHHMI
ディレクトリで確認できます。
-
100%ラインカバレッジ:7/7
-
63%の突然変異率:5/8
明らかに、私たちのテストはすべての実行パスに渡って掃引するので、ラインカバレッジスコアは100%です。一方、PITestライブラリは
8つの突然変異体
を導入し、そのうち5つが殺されました – 失敗の原因となりました – しかし3つは生き残りました。
作成された突然変異体についての詳細は、
com.baeldung.testing.mutation/Palindrome.java.html
レポートを確認してください。
リンク:/uploads/mutations.png%20715w[]
ミューテーションカバレッジテストを実行するとき、これらはデフォルトでアクティブなミューテーターです。
-
INCREMENTS
MUTATOR__ -
VOID
METHOD
CALL
MUTATOR__ -
RETURN
VALS
MUTATOR
-
MATH
MUTATOR__ -
NEGATE
CONDITIONALS
MUTATOR
-
INVERT
NEGS
MUTATOR
-
CONDITIONALS
BOUNDARY
MUTATOR
PITestミューテーターの詳細については、公式の
documentation page
リンクを確認できます。
私たちの突然変異カバレッジスコアは
私たちの回文関数が非回文とほぼ回文文字列入力を拒否することを確認できないので
テストケースの欠如** を反映しています。
6. 変異スコアを向上させる
突然変異とは何かがわかったので、生き残った突然変異体を殺すことによって突然変異スコアを向上させる必要があります。
例として、6行目の条件付きで否定された最初の突然変異を見てみましょう。コードスニペットを変更しても、ミュータントは生き残りました。
if (inputString.length() == 0) {
return true;
}
に:
if (inputString.length() != 0) {
return true;
}
テストは成功します、そしてそれは
突然変異が生き残った
理由です。その考えは、変異体が導入された場合には** 失敗するという新しいテストを実装することです。残りの変異体についても同じことができます。
@Test
public void whenNotPalindrom__thanReject() {
Palindrome palindromeTester = new Palindrome();
assertFalse(palindromeTester.isPalindrome("box"));
}
@Test
public void whenNearPalindrom__thanReject() {
Palindrome palindromeTester = new Palindrome();
assertFalse(palindromeTester.isPalindrome("neon"));
}
これで、ターゲットディレクトリに生成されたPITestレポートでわかるように、
すべての突然変異が殺された
ことを確認するために、突然変異補償プラグインを使ってテストを実行できます。
-
100%ラインカバレッジ:7/7
-
100%の突然変異率:8/8
7. PITestテストの設定
突然変異テストはリソースを大量に使用することがあるので、テストの有効性を向上させるために適切な設定を行う必要があります。
targetClasses
タグを使用して、変更するクラスのリストを定義できます。突然変異テストは、実時間のプロジェクトのすべてのクラスに適用できるわけではありません。時間がかかり、リソースが重要になるためです。
テストの実行に必要なコンピューティングリソースを最小限に抑えるために、突然変異テスト中に使用する予定のミューテーターを定義することも重要です。
<configuration>
<targetClasses>
<param>com.baeldung.testing.mutation.** </param>
</targetClasses>
<targetTests>
<param>com.baeldung.mutation.test.** </param>
</targetTests>
<mutators>
<mutator>CONSTRUCTOR__CALLS</mutator>
<mutator>VOID__METHOD__CALLS</mutator>
<mutator>RETURN__VALS</mutator>
<mutator>NON__VOID__METHOD__CALLS</mutator>
</mutators>
</configuration>
さらに、PITestライブラリには、
テスト戦略をカスタマイズする
ために利用可能なさまざまなオプションがあります。たとえば、
maxMutationsPerClass
オプションを使用して、クラスごとに導入される突然変異体の最大数を指定できます。 PITestオプションの詳細については、公式
Mavenクイックスタートガイド
を参照してください。
8結論
コードカバレッジは依然として重要な指標ですが、十分にテストされたコードを保証するのに十分ではない場合があります。そのため、この記事では、
PITestライブラリー
を使用して、テストの品質を保証し、テストケースを保証するためのより洗練された方法として、
突然変異テスト
について説明しました。
また、
突然変異率のスコア
を改善しながら、基本的なPITestレポートを分析する方法も見ました。
突然変異テストはコードの欠陥を明らかにしますが、それは非常に
高価で時間のかかるプロセス
であるため、賢く使用されるべきです。
この記事で提供されている例は、リンクされたhttps://github.com/eugenp/tutorials/tree/master/testing-modules/testing[
GitHubプロジェクト
]で確認できます。