Gradle でテストを並列実行してみる
Gradle の Java プラグインには テストを並列で実行するための機能が標準で用意されています。
通常は テスト用のプロセスは 1つしか立ち上がりませんが、
test.maxParallelForks = 5のように設定すれば 最大 5プロセスで並列実行できるようになります。
もちろん、最近、お気に入りの Spock でも ちゃんと並列処理できます。
並列処理は クラス単位で行われるため 時間のかかる (しかも、CPU時間の少ない) メソッドが多い場合は リファクタリングしてクラスを分けた方がよいです。
内部クラスでも それぞれ ちゃんと並列処理してくれるので、ファイルはそのままで クラスだけ分けることもできます。
例えば...
class HelloSpock extends spock.lang.Specification { def "30秒後に目が覚めて挨拶する"() { Hello hello = new Hello("FOO"); hello.sleep(30) expect: hello.greeting() == "Hello, FOO." } def "30秒後に目が覚めて挨拶する"() { Hello hello = new Hello("BAR"); hello.sleep(30) expect: hello.greeting() == "Hello, BAR." } def "30秒後に目が覚めて挨拶する"() { Hello hello = new Hello("HOGE"); hello.sleep(30) expect: hello.greeting() == "Hello, HOGE." } }のように一つのクラスに 30 秒ずつかかるメソッドがある場合、いくら並列処理するように設定しても 一つのプロセスで処理するので 90 秒かかりますが、
class HelloFooSpock extends spock.lang.Specification { def "30秒後に目が覚めて挨拶する"() { Hello hello = new Hello("FOO"); hello.sleep(30) expect: hello.greeting() == "Hello, FOO." } } class HelloBarSpock extends spock.lang.Specification { def "30秒後に目が覚めて挨拶する"() { Hello hello = new Hello("BAR"); hello.sleep(30) expect: hello.greeting() == "Hello, BAR." } } class HelloHogeSpock extends spock.lang.Specification { def "30秒後に目が覚めて挨拶する"() { Hello hello = new Hello("HOGE"); hello.sleep(30) expect: hello.greeting() == "Hello, HOGE." } }のように内部クラスで分離すれば、3プロセスで処理されるので、30 秒 + α で実行できます。
あと、
test.forkEvery = 3のように設定すると 一定数 テストクラスを実行したらプロセスを再起動することもできます。
上記の場合だと 同じプロセスで 3つの テストクラスを実行したら再起動されます。