Java 在 Maven 构建中并行运行 junit 测试?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/423627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Running junit tests in parallel in a Maven build?
提问by krosenvold
I'm using JUnit 4.4 and Maven and I have a large number of long-running integration tests.
我正在使用 JUnit 4.4 和 Maven,并且我有大量长时间运行的集成测试。
When it comes to parallelizing test suites there are a few solutions that allow me to run each test method in a single test-class in parallel. But all of these require that I change the tests in one way or another.
当谈到并行化测试套件时,有一些解决方案允许我在单个测试类中并行运行每个测试方法。但是所有这些都要求我以一种或另一种方式更改测试。
I really think it would be a much cleaner solution to run X different test classes in X threads in parallel. I have hundreds of tests so I don't really care about threading individual test-classes.
我真的认为在 X 个线程中并行运行 X 个不同的测试类会是一个更清晰的解决方案。我有数百个测试,所以我并不真正关心线程化单个测试类。
Is there any way to do this?
有没有办法做到这一点?
采纳答案by krosenvold
From junit 4.7 it's now possible to run tests in parallel without using TestNG. Actually it has been possible since 4.6, but there are a number of fixes being made in 4.7 that will make it a viable option. You may also run parallel tests with spring, which you can read about here
从 junit 4.7 开始,现在可以在不使用 TestNG 的情况下并行运行测试。实际上,从 4.6 开始就可以了,但是在 4.7 中进行了许多修复,使其成为一个可行的选择。您还可以使用 spring 运行并行测试,您可以在此处阅读
回答by philant
TestNG can do that(this was my first reflex - then I saw you're already having a lot of testcases).
TestNG 可以做到这一点(这是我的第一个反应——然后我看到你已经有很多测试用例了)。
For JUnit, look at parallel-junit.
对于 JUnit,请查看parallel-junit。
回答by philant
You can change your test to be TestNg test in a minute (you just need to change imports), TestNG is the best in parallel testing.
您可以在一分钟内将您的测试更改为TestNg测试(您只需要更改导入),TestNG是并行测试中最好的。
回答by Jan Kronquist
回答by Toby
tempus-fugitoffers something similar, check the docs for details. It relies on JUnit 4.7 and you just mark your test to @RunWith(ConcurrentTestRunner)
.
tempus-fugit提供了类似的东西,查看文档了解详细信息。它依赖于 JUnit 4.7,您只需将测试标记为@RunWith(ConcurrentTestRunner)
.
Cheers
干杯
回答by Pavan
You can check out the open source library - Test Load Balancer. It does exactly what you ask for - run different test classes in parallel. This integrates at the ant-junit level so that you do not have to change your tests in anyway. I am one of the authors of the library.
您可以查看开源库 - Test Load Balancer。它完全符合您的要求 - 并行运行不同的测试类。这在 ant-junit 级别集成,因此您不必以任何方式更改测试。我是图书馆的作者之一。
Also, think about not running them in threads as you may need a process level sandbox. For example, if you are hitting a DB in your integration tests, you do not want one test to fail because another test added some data in a different thread. Most of the times, tests are not written with this in mind.
另外,考虑不要在线程中运行它们,因为您可能需要一个进程级沙箱。例如,如果您在集成测试中遇到数据库,您不希望一个测试失败,因为另一个测试在不同的线程中添加了一些数据。大多数时候,编写测试时并没有考虑到这一点。
Finally, how have solved this problem till now?
最后,到目前为止这个问题是如何解决的?
回答by Oleksandr
Use maven plugin:
使用 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>
回答by Mustafa Ulu
Inspired by JUnit's experimental ParallelComputerrunner I've built my own ParallelSuiteand ParallelParameterizedrunners. Using these runners one can easily parallelize test suites and parameterized tests.
受 JUnit 的实验性ParallelComputer 运行器的启发,我构建了自己的ParallelSuite和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
并行参数化.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);
}
}
});
}
}
Usage is simple. Just change @RunWithannotations value to one of these Parallel*classes.
用法很简单。只需将@RunWith注释值更改为这些Parallel*类之一。
@RunWith(ParallelSuite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {}
回答by Ashwin Sadeep
You can run the tests in parallel using ParallelComputer provided by Junit itself. Here's a small snippet to get you started.
您可以使用 Junit 本身提供的 ParallelComputer 并行运行测试。这是一个小片段,可以帮助您入门。
Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();
This will help when you need to run tests from code as it has no dependencies on Maven or any other build management tools.
当您需要从代码运行测试时,这将有所帮助,因为它不依赖于 Maven 或任何其他构建管理工具。
Please note that, this will run all test cases in parallel, if you have any dependencies between different test cases it might result in false positives. You SHOULD NOT have interdependent tests anyway.
请注意,这将并行运行所有测试用例,如果不同测试用例之间存在任何依赖关系,则可能会导致误报。无论如何,您不应该进行相互依赖的测试。
回答by Guilin Sun
Another choice: Punner, a new parallel junit runner and maven plugin. You don't have to change your code, copy it to your pom.xml:
另一个选择:Punner,一个新的并行 junit 运行器和 maven 插件。您不必更改代码,将其复制到您的 pom.xml 中:
<!-- Disable default surefire based testing -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>com.github.marks-yag</groupId>
<artifactId>punner-maven-plugin</artifactId>
<version>${version}</version>
<configuration>
</configuration>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
Punner can run test methods in parallel, can keep test outputs separately and clean.
Punner 可以并行运行测试方法,可以保持测试输出分开和干净。
Punner will reduce your mvn console outputs, like this:
Punner 将减少您的 mvn 控制台输出,如下所示:
[INFO] --- punner-maven-plugin:0.9.13:test (test) @ ipc ---
[INFO] Punner report directory: /Users/guile/workspace/ipc/target/punner-reports
[INFO]
[INFO] com.github.yag.ipc.IPCTest.testConnectionHandler.............. PASSED
[INFO] com.github.yag.ipc.IPCTest.testSequence....................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testPartialContent................. PASSED
[INFO] com.github.yag.ipc.IPCTest.testResponseContent................ PASSED
[INFO] com.github.yag.ipc.IPCTest.testPingPong....................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testServerClose.................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testServerSideHeartbeatTimeout..... PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientSideHeartbeatTimeout..... PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientSideHeartbeat............ PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientReconnect................ PASSED
[INFO]
[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.952 sec, Time saved: 25.919 sec.
Punner produce surefire compatible outputs, you can also get raw log data and a markdown format report from reports directory:
Punner 产生了万无一失的兼容输出,您还可以从报告目录中获取原始日志数据和降价格式报告:
? ipc git:(develop) ll target/punner-reports
total 104
-rw-r--r-- 1 guile staff 11K Oct 15 23:07 TEST-com.github.yag.ipc.IPCTest.xml
-rw-r--r-- 1 guile staff 298B Oct 15 23:07 com.github.yag.ipc.IPCTest.txt
drwxr-xr-x 12 guile staff 384B Oct 8 00:50 logs
-rw-r--r-- 1 guile staff 33K Oct 15 23:07 report.md
Punner is my personal project, I written Punner to speed up unit test phase of some other projects such as IPC framework, fine-grained locking, journal service, distributed workflow engine, etc. It saved a lot of my waiting time.
Punner 是我的个人项目,我编写 Punner 是为了加快其他一些项目的单元测试阶段,例如 IPC 框架、细粒度锁定、日志服务、分布式工作流引擎等。它节省了我很多等待时间。
Punner don't support some advanced feature yet. I'm very glad if you could try it and give me some feedback.
Punner 尚不支持某些高级功能。如果您可以尝试并给我一些反馈,我很高兴。