例としてPitestを使用した突然変異テスト

皆さんの多くは、素晴らしいPodcast DebriefingポッドキャストでMutation Testingについて聞いたことがあるか、 Wikipediaで読んだことがあります。 まだ概念に慣れていない人のために、簡単に説明します。



突然変異テストは、 テストの品質を測定するための代替アプローチです。 一般的なコードカバレッジをカウントする代わりに、より合理的なメカニズムが使用されます。 ランダムクラス(別名、 ミューテーション)は、クラスのバイトコードに導入されます。 そのような突然変異の後に行われた変更をカバーする単一のテストが落ちなかった場合、テストであまりうまくやっていない可能性があります。 可能な突然変異の例:

それは:
if(somevalue < threshold) { doSomething(); }
      
      



次のようになりました:
 if(somevalue >= threshold) { doSomething(); }
      
      



このコードブロックをカバーするテストは必ず実行される必要があるため、変更は非常に重要です。 カットの下で、非常に優れたPitestライブラリについて説明し、それをプロジェクトに接続する方法を示し、テスト結果を実際のコードで提供します。



シンプルなプロジェクト

単一のクラスを含む単純な[ github ]プロジェクトから始めましょう。

 1 2 3 4 5 6 8
      
      



 public class ClassToTest { private static final double THRESHOLD = 10.0; public static boolean threshold(double value) { return value >= THRESHOLD; } }
      
      



そしてそれをテストします:

 1 2 3 4 5
      
      



 @Test public void testThreshold() { Assert.assertTrue(ClassToTest.threshold(10.0)); Assert.assertFalse(ClassToTest.threshold(9.0)); }
      
      







pitestを接続するには、プラグインをmavenに追加するだけです:

 1 2 3 4 5 6 7 8 9 10 11 12 13
      
      



 <plugin> <groupId>org.pitest</groupId> <artifactId>pitest-maven</artifactId> <version>0.25</version> <configuration> <inScopeClasses> <param>com.example*</param> </inScopeClasses> <targetClasses> <param>com.example*</param> </targetClasses> </configuration> </plugin>
      
      



構成についてもう少し詳しく説明しますinScopeClasses



は、変更する必要があるテストとクラスを探すためのクラスを定義します。 targetClasses



は、変更するだけのクラスを定義します。 さらに、いくつかのオプションがあり、その完全なリストはこちらにあります



何らかの理由でmavenを使用していない場合、すべてがなくなっているわけではありません。コマンドラインから使用できます 。マニュアルはこちらから入手できます



そして、mavenを使用して幸せを見つけるには、次のコマンドを実行します。
 mvn org.pitest:pitest-maven:mutationCoverage
      
      



レポートについて

チェックの結果、ログのシートがかなり大きくなります。 読むのは特に便利ではありませんが、 target/pit-reports/%TIMESTAMP%



フォルダーでは、コードカバレッジに類似したhtmlレポートも生成されます。 私たちの場合、その興味深い部分は次のようになります。







ここの行14に近い3番目の数字は、この行に適用された突然変異の数を意味します。 以下の突然変異セクションでは、各ラインについて、どの突然変異が適用され、結果がどうであったかを説明しています。



突然変異の結果



突然変異の種類



現時点では、11の突然変異しかない。 緑色で強調表示されているのは、デフォルトで有効になっているものです。 さまざまなタイプの突然変異の詳細な説明は、公式ウェブサイトで入手できます。



例の複雑化



サンプルプロジェクトでは、突然変異は条件(2個)と戻り値にありました。 ここで、より多くの突然変異を達成してみましょう。 クラス自体を次のように書き換えます。

 1 2 3 4 5 6 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
      
      



 public class ClassToTest { private int invocationCount = 0; private static final double OFFSET = 1.0; private final double threshold; public ClassToTest(double threshold) { this.threshold = threshold; } public boolean threshold(double value) { logInvocation(); return value >= threshold + OFFSET; } private void logInvocation() { invocationCount++; } }
      
      



しかし、テストでは、新しい機能をテストしません。

 1 2 3 4 5 6 7
      
      



 @Test public void testThreshold() { ClassToTest classToTest = new ClassToTest(10.0); Assert.assertTrue(classToTest.threshold(11.0)); Assert.assertFalse(classToTest.threshold(10.0)); }
      
      



コードカバレッジを実行する場合、問題は検出されません。 しかし、突然変異テストを実行すると、彼らはすぐに手で私たちをつかんで言います:しかし、機能はテストされていません!







成功! これで、実際にテストされるコードとテストされないコードをかなり正確に言うことができ、実際には何もチェックしないあらゆる種類の「推定」テストが迅速に検出されます。



なぜまさにピストですか?

一般的に言えば、突然変異テストの考え方は新しいものではなく、いくつかのライブラリがすでに存在しています。 これらの中で最も注目すべきはJavalancheJumbleです。 ただし、これらのライブラリやその他のライブラリは特に積極的に開発されているわけではありません。一部のライブラリは低速でバグが多く、ビルドシステムやその他のライブラリとは実質的に統合されていません。 詳細な比較はこちらから入手できます



実際のプロジェクトを確認する

興味を引くために、実際のプロジェクトで、コードカバレッジでは検出できない問題を突然変異テストで検出する方法を示すのが正しいでしょう。 これには、コードカバレッジを読み取るユーティリティであるCoberturaが最適です。 彼女のレポートはここで完全に見つけることができます、そして私はほんの少しだけを与えます。 それを得るには、ソースにmavenのサポートを追加して少し汗をかき、 約20分間待機する必要がありました。その間、突然変異のテストが続きます。 。 結果は次のとおりです。

Coberturaは、すべてが正常であることを示しています。
Pitestはカバーを引き裂きます。




合計

全体として、このアプローチはクールであり、コードカバレッジよりもはるかに正確にテストの品質を明確に評価します。 もちろん、このようなチェックは通常のカバレッジよりもはるかに長く機能するため、大規模なプロジェクトでは数時間かかる場合があります。 さらに、Pitestライブラリ自体はまだ多少湿っています。 たとえば、複数のスレッドでテストを実行したり、すべてのテストを変更せずに正常に完了したりすることはできません。 しかし、このプロジェクトはオープンソースであり、非常に活発に開発されているため、しばらくしてから真剣に使用することについて考え始めることができると信じています。



質問、コメント、コメントの修正を待っています!



All Articles