Mavenビルドでjunitテストを並行して実行していますか?
質問
私はJUnit 4.4とMavenを使用しており、長時間実行される統合テストが多数あります。
テストスイートの並列化に関しては、単一のテストクラスで各テストメソッドを並列に実行できるソリューションがいくつかあります。しかし、これらはすべて、何らかの方法でテストを変更する必要があります。
XスレッドでX個の異なるテストクラスを並行して実行することは、非常にクリーンなソリューションになると本当に思います。私には何百ものテストがあるので、個々のテストクラスをスレッド化することはあまり気にしません。
これを行う方法はありますか?
解決 2
junit 4.7から、TestNGを使用せずにテストを並行して実行できるようになりました。実際、4.6から可能になりましたが、4.7で実行可能なオプションとなる多くの修正が行われています。 springで並列テストを実行することもできます。これはこちら
他のヒント
mavenプラグインを使用:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>5</threadCount>
</configuration>
</plugin>
</plugins>
</build>
JUnitの実験的な に触発されたParallelComputer ランナー ParallelSuite および< strong> ParallelParameterized ランナー。これらのランナーを使用すると、テストスイートとパラメーター化されたテストを簡単に並列化できます。
ParallelSuite.java
public class ParallelSuite extends Suite {
public ParallelSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(klass, builder);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(4);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
ParallelParameterized.java
public class ParallelParameterized extends Parameterized {
public ParallelParameterized(Class<?> arg0) throws Throwable {
super(arg0);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(8);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
使い方は簡単です。 @RunWith アノテーションの値をこれらの Parallel * クラスのいずれかに変更するだけです。
@RunWith(ParallelSuite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {}
tempus-fugit は同様の機能を提供します。詳細についてはドキュメントを確認してください。 JUnit 4.7に依存しており、テストを @RunWith(ConcurrentTestRunner)
にマークするだけです。
乾杯
TestNGはこれを実行できます(これは私の最初の反射でした-その後、すでに多くのテストケースを持っていることがわかりました)。
JUnitについては、 parallel-junit をご覧ください。
オープンソースライブラリ- Test Load Balancer を確認できます。それはまさにあなたが求めることをします-異なるテストクラスを並行して実行します。これは、ant-junitレベルで統合されるため、テストを変更する必要はありません。私は図書館の著者の一人です。
また、プロセスレベルのサンドボックスが必要になる可能性があるため、スレッドで実行しないことを検討してください。たとえば、統合テストでDBにアクセスする場合、別のテストが別のスレッドにデータを追加したため、1つのテストが失敗することは望ましくありません。ほとんどの場合、テストはこれを念頭に置いて書かれていません。
最後に、これまでこの問題をどのように解決しましたか?
Junit自体が提供するParallelComputerを使用して、テストを並行して実行できます。始めに使用する小さなスニペットを次に示します。
Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();
Mavenやその他のビルド管理ツールに依存しないため、コードからテストを実行する必要がある場合に役立ちます。
これにより、すべてのテストケースが並行して実行されることに注意してください。異なるテストケースの間に依存関係がある場合、誤検知が発生する可能性があります。とにかく相互依存テストを行うべきではありません。
1分でテストをTestNgテストに変更できます(インポートを変更するだけです)。TestNGは並列テストに最適です。
実行できる Gridgain を試すことができます計算グリッド全体にテストを分散します。