Mavenと並行してJUnitテストを実行する
1. 前書き
テストを連続して実行することは、ほとんどの場合うまく機能しますが。 場合によっては、速度を上げる必要があります。 これらの状況では、並列テストが役立ちます。
JUnit 4.7 and later versions make it possible to execute tests in parallel using Maven’s Surefire Plugin。 簡単に言えば、Surefireはテストを並行して実行する2つの方法を提供します。
-
最初のアプローチでは、単一のJVMプロセス内でマルチスレッドを使用します
-
2番目のアプローチは複数のJVMプロセスを使用しますが
このチュートリアルでは、単一のJVMプロセス内でJUnitテストを並行して実行するようにSurefireを構成する方法について説明します。 次に、Mavenマルチモジュールプロジェクト内でテストを並行して実行する方法を説明します。
2. Mavenの依存関係
必要な依存関係をインポートすることから始めましょう。 We’ll need to use JUnit 4.7 or later along with Surefire 2.16 or later:
junit
junit
4.12
test
org.apache.maven.plugins
maven-surefire-plugin
2.22.0
3. 並列テストの実行
テストを並行して実行するには、org.junit.runners.ParentRunnerを拡張するテストランナーを使用する必要があります。
ただし、デフォルトのランナーがこのクラスを拡張するため、明示的なテストランナーの動作を宣言していないテストでも機能します。
次に、並列テストの実行を示すために、それぞれにいくつかのメソッドを持つ2つのテストクラスを持つテストスイートを使用します。 実際、JUnitテストスイートの標準実装はすべて実行されます。
3.1. 並列パラメーターの使用
まず、parallel パラメータを使用してSurefireで並列動作を有効にしましょう。 It states the level of granularity at which we would like to apply parallelism.
可能な値は次のとおりです。
-
methods – は別々のスレッドでテストメソッドを実行します
-
classes –は、別々のスレッドでテストクラスを実行します
-
classesAndMethods –は、クラスとメソッドを別々のスレッドで実行します
-
suites – runsスイートを並行して
-
suitesAndClasses – は、スイートとクラスを別々のスレッドで実行します
-
suitesAndMethods – は、クラスとメソッドに別々のスレッドを作成します
-
all –は、スイート、クラス、およびメソッドを別々のスレッドで実行します
この例では、allを使用します。
all
次に、Surefireで作成するスレッドの総数を定義しましょう。 これには2つの方法があります。
Surefireが作成するスレッドの最大数を定義するthreadCountを使用する:
10
または、CPUコアごとに1つのスレッドが作成されるuseUnlimitedThreadsパラメータを使用します。
true
デフォルトでは、threadCountはCPUコアごとです。 パラメータperCoreThreadCountを使用して、この動作を有効または無効にできます。
true
3.2. スレッドカウントの制限の使用
ここで、メソッド、クラス、およびスイートレベルで作成するスレッドの数を定義するとします。 We can do this with the threadCountMethods, threadCountClasses and threadCountSuites parameters.
これらのパラメータを前の構成のthreadCountと組み合わせてみましょう:_ _
2
2
6
parallel, でallを使用したため、メソッド、スイート、およびクラスのスレッド数を定義しました。 ただし、リーフパラメータを定義することは必須ではありません。 Surefireは、リーフパラメーターが省略された場合に使用するスレッドの数を推測します。
たとえば、threadCountMethodsが省略されている場合は、threadCount>threadCountClasses +threadCountSuites.を確認する必要があります。
スレッドの数に制限がない場合でも、クラス、スイート、またはメソッド用に作成されるスレッドの数を制限したい場合があります。
そのような場合にもスレッド数の制限を適用できます。
true
2
3.3. タイムアウトの設定
テストの実行が時間制限されていることを確認する必要がある場合があります。
To do that we can use the parallelTestTimeoutForcedInSeconds parameter.これにより、現在実行中のスレッドが中断され、タイムアウトが経過した後、キューに入れられたスレッドは実行されません。
5
もう1つのオプションは、parallelTestTimeoutInSecondsを使用することです。
この場合、キューに入っているスレッドのみの実行が停止されます。
3.5
それでも、両方のオプションを使用すると、タイムアウトが経過すると、テストはエラーメッセージで終了します。
3.4. 注意事項
Surefireは、親スレッドで@Parameters、@BeforeClass、および@AfterClassでアノテーションが付けられた静的メソッドを呼び出します。 したがって、テストを並行して実行する前に、潜在的なメモリの不一致または競合状態を必ず確認してください。
また、共有状態を変更するテストは、並行して実行するのに適した候補ではありません。
4. マルチモジュールMavenプロジェクトでのテスト実行
これまで、Mavenモジュール内で並行してテストを実行することに焦点を当ててきました。
しかし、Mavenプロジェクトに複数のモジュールがあるとしましょう。 これらのモジュールは順番に構築されるため、各モジュールのテストも順番に実行されます。
We can change this default behavior by using Maven’s -T parameter which builds modules in parallel。 これには2つの方法があります。
プロジェクトのビルド中に使用するスレッドの正確な数を指定できます。
mvn -T 4 surefire:test
または、ポータブルバージョンを使用して、CPUコアごとに作成するスレッドの数を指定します。
mvn -T 1C surefire:test
いずれにせよ、テストを高速化し、実行時間を構築できます。
5. 結論
要約すると、マルチスレッド動作を有効にし、parallelパラメータを使用して並列度を定義することから始めました。 その後、Surefireが作成するスレッドの数に制限を適用しました。 後で、テストの実行時間を制御するためにタイムアウトパラメーターを設定しました。
最後に、ビルド実行時間を短縮し、マルチモジュールMavenプロジェクトで実行時間をテストする方法を検討しました。
いつものように、ここに表示されるコードはavailable on GitHubです。