私は現在、mavenを使用してJavaプロジェクトに取り組んでいます。ビルドプロセスの一部として、mavenのsurefireプラグインを使用してjunitスイートを実行しています。
私たちのテストスイートは、カバレッジと実行時間の両方で急速に成長しています。テストの最初の1分間にテストが失敗したことを確認するために、10分間待機することになった場合、実行時間は非常に苛立たしく、時間がかかります。
テストスイートの最初のエラー/失敗時にビルドプロセスを失敗させる方法を見つけたいと思います。これは他のビルドツールでも可能であることは知っていますが、mavensurefireでこれを行う方法を見つけることができませんでした。
Surefire jiraに この機能の未解決のチケット があることは知っていますが、これに対する既存のソリューションがあることを望んでいます。
2015年9月6日現在 あるようです 、-Dsurefire.skipAfterFailureCount=1
。
2015年10月19日現在 バージョン2.19がリリースされました 。
私の知る限り、noであり、これには本当に SUREFIRE-58 の解像度が必要です。これをより早く実現したい場合は、少なくとも問題に投票し、オプションでパッチを送信する必要があります;)
適切な回避策があるかもしれませんが、それは要件によって異なり、jvmプロセスのリターンコードを処理できるCIサーバーを使用する必要があります。
基本的な考え方は、MavenのJVMプロセスを完全に停止し、プロセスが予期せず停止したことをOSに通知することです。次に、Jenkins/Hudsonのような継続的インテグレーションサーバーゼロ以外の終了コードをチェックできるはずですそしてテストが失敗したことを通知します。
最初のステップは、最初のテストの失敗時に確実にJVMを終了することです。カスタムRunListener
(src/test/Javaに配置)を使用して、JUnit4.7以降でこれを行うことができます。
package org.example
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
public class FailFastListener extends RunListener {
public void testFailure(Failure failure) throws Exception {
System.err.println("FAILURE: " + failure);
System.exit(-1);
}
}
次に、そのクラスを構成して、surefireがそのクラスをJUnit 4Runnerに登録するようにする必要があります。 pom.xml
を編集し、listener
構成プロパティをmaven-surefire-pluginに追加します。また、テストを実行するには、新しいJVMプロセスをフォークしないようにsurefireを構成する必要があります。それ以外の場合は、次のテストケースに進みます。
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<forkMode>never</forkMode>
<properties>
<property>
<name>listener</name>
<value>org.example.FailFastListener</value>
</property>
</properties>
</configuration>
</plugin>
これで問題が解決しない場合は、Mavenのsurefirejunitプロバイダープラグインをフォークしてみます。
ところで、ユニットテストは、定義上、0.1秒より速く実行する必要があります。単体テストのためにビルドに本当に時間がかかる場合は、将来的にビルドを高速化する必要があります。
maven
は--fail-fast
オプションで実行できます。
-ff
オプションは、開発サイクル中に迅速なフィードバックが必要なインタラクティブビルドを実行している開発者にとって非常に便利です。
例は次のとおりです。
mvn clean test -ff
http://books.sonatype.com/mvnref-book/reference/running-sect-options.html
正確に必要なものではない場合でも、速度を上げるためのいくつかの方法:
マルチモジュールビルドの場合は、コマンドラインに--fail-fastを追加して、最初のモジュールの後にドロップアウトします。
フェイルセーフを調べて、長時間実行される統合テストをライフサイクルの別のフェーズに移動します。
高速テストと低速テストのプロファイルベースのソリューションを調べてください- 特定のパッケージのテストをスキップするようにsurefireに指示する方法はありますか? 。
これは質問に対する直接の答えではありませんが、mavenの出力をgrepを介してフィードし、ほとんどのものを取り除き、テストの失敗がどこにあるかを確認するのに役立つ場合もあります。
このような:
mvn test | grep -w 'Running\|Tests'
これは(私のコードの)次のような出力を生成します:
Running scot.mygov.pp.test.dashboard.DashboardJsonSerDesCRUDTest
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.029 sec
Running scot.mygov.pp.test.dashboard.DashboardBaselineCRUDTest
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.026 sec
Running scot.mygov.pp.test.dashboard.DashboardDatabaseValidationTest
Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.264 sec
Running scot.mygov.pp.test.dashboard.DashboardServiceWebServiceIsolationCRUDTest
Tests run: 26, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.032 sec
失敗の最初のエラーがどこにあるかを確認するのがはるかに簡単です。
これは問題を正確に解決するわけではありませんが、私の職場が最終的に思いついた解決策は、AtlassianのCloverを使用して、変更されたコードに関連するテストだけの特殊なビルドを実行することでした。
変更されたコードのテストを実行し、完全なテストビルドを開始するCloverビルドがあります。
これは満足のいく解決策であることが証明されています。