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つの テストクラスを実行したら再起動されます。