JUnit 5並列実行
テストの並列実行
デフォルトでは、すべてのテストメソッドは単一スレッドで順次実行される。JUnit 5では設定によりテストを並列実行できる。
並列実行の有効化
クラスパスのルートにjunit-platform.propertiesを作成し、並列実行を有効にする。
/test/resource/junit-platform.properties
junit.jupiter.execution.parallel.enabled=true
この設定だけではテストメソッドは並列にならない。メソッドを並列実行するには、テストクラスに@Execution(ExecutionMode.CONCURRENT)を設定する。SAME_THREADは親と同じスレッドで実行し、デフォルト値である。
デフォルト実行モードの変更
次のプロパティを設定すると、メソッドのデフォルト実行モードが並列実行になる。
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=concurrent
ただし、Lifecycle.PER_CLASSを指定したテストクラスや、MethodOrderer.Random以外の順序指定テストは、このデフォルト並列モードの例外になる。スレッドセーフで並列実行したい場合は、明示的に@Execution(ExecutionMode.CONCURRENT)を付ける。
最上位クラスのデフォルト変更
junit.jupiter.execution.parallel.mode.classes.default=concurrentは、最上位クラスのデフォルト実行モードだけを変更する。この設定では、異なるテストクラスは別スレッドで実行され、各クラス内のメソッドは順次実行される。
設定別の実行
junit.jupiter.execution.parallel.mode.defaultとjunit.jupiter.execution.parallel.mode.classes.defaultの組み合わせにより、4つの動作になる。
- 両方
same_thread: クラスとメソッドを順次実行する。 - メソッド
same_thread、クラスconcurrent: クラスごとに並列実行し、クラス内メソッドは順次実行する。 - メソッド
concurrent、クラスsame_thread: クラス内メソッドは並列実行し、クラスは順次実行する。 - 両方
concurrent: クラスとメソッドをすべて並列実行する。

並列数の変更
dynamic戦略では、junit.jupiter.execution.parallel.config.dynamic.factorに利用可能プロセッサ数を掛けて、並列実行スレッド数を決定する。
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.config.strategy=dynamic
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.parallel.config.dynamic.factor=2
factorには小数も指定できる。JUnitは内部でBigDecimalを使い、計算結果をintへ変換する。
固定値を使う場合はfixedを指定し、junit.jupiter.execution.parallel.config.fixed.parallelismで並列数を指定する。
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.config.strategy=fixed
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.parallel.config.fixed.parallelism=6
任意にカスタマイズする場合はParallelExecutionConfigurationStrategyを実装し、junit.jupiter.execution.parallel.config.custom.classで指定する。
排他制御
排他制御は、共有リソースへ複数テストが同時アクセスしても問題が起きないようにする制御である。クラスまたはメソッドに@ResourceLockを付ける。同じロックキーを持つテストは同期される。
アクセスモード
@ResourceLockはResourceAccessModeによるアクセスモードをサポートする。
| 先行している処理 | 後から発生した処理 | 後から発生した処理 |
|---|---|---|
| READ | READ | 実行可能 |
| READ | READ_WRITE | 待機 |
| READ_WRITE | READ | 待機 |
| READ_WRITE | READ_WRITE | 待機 |
READだけなら並列実行可能だが、READ_WRITEがある場合は排他制御される。データを読むだけのテストにはREAD、更新するテストにはREAD_WRITEを指定する。