我正在使用JUnit 4.4和Maven,并且我有大量长时间运行的集成测试。
在并行化测试套件时,有一些解决方案允许我在一个测试类中并行运行每个测试方法。但所有这些都要求我以这种或那种方式改变测试。
我真的认为在X线程中并行运行X个不同的测试类会是一个更清晰的解决方案。我有数百个测试,所以我并不真正关心线程化各个测试类。
有没有办法做到这一点?
答案 0 :(得分:70)
使用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>
答案 1 :(得分:40)
从junit 4.7开始,现在可以在不使用TestNG的情况下并行运行测试。实际上从4.6开始就有可能,但是4.7中有一些修正,这将使它成为一个可行的选择。您也可以使用spring运行并行测试,您可以阅读here
答案 2 :(得分:10)
受到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 强>
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 注释值更改为其中一个并行* 类。
@RunWith(ParallelSuite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {}
答案 3 :(得分:5)
tempus-fugit提供类似的内容,请查看文档以获取详细信息。它依赖于JUnit 4.7,您只需将测试标记为@RunWith(ConcurrentTestRunner)
。
干杯
答案 4 :(得分:3)
TestNG can do that(这是我的第一次反应 - 然后我看到你已经有了很多测试用例)。
对于JUnit,请查看parallel-junit。
答案 5 :(得分:3)
您可以查看开源库 - Test Load Balancer。它完全符合您的要求 - 并行运行不同的测试类。它集成在ant-junit级别,因此您无需进行任何更改测试。我是图书馆的作者之一。
另外,请考虑不要在线程中运行它们,因为您可能需要一个进程级别的沙箱。例如,如果您在集成测试中遇到数据库,则不希望一个测试失败,因为另一个测试在另一个线程中添加了一些数据。大多数时候,考试都不是考虑到这一点。
最后,到现在为止如何解决这个问题?
答案 6 :(得分:2)
您可以使用Junit自己提供的ParallelComputer并行运行测试。这是一个可以帮助您入门的小片段。
Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();
当您需要从代码运行测试时,这将有所帮助,因为它不依赖于Maven或任何其他构建管理工具。
请注意,这将并行运行所有测试用例,如果不同测试用例之间存在任何依赖关系,则可能导致误报。无论如何,你不应该有相互依赖的测试。
答案 7 :(得分:0)
另一个选择: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可以并行运行测试方法,可以分开保存测试输出并保持干净。
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产生与surefire兼容的输出,您还可以从报告目录获取原始日志数据和降价格式报告:
➜ 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是我的个人项目,我写了Punner来加快其他一些项目的单元测试阶段,例如IPC框架,细粒度的锁定,日记服务,分布式工作流引擎等。它节省了很多我的等待时间。
Punner尚不支持某些高级功能。如果您可以尝试并给我一些反馈,我感到非常高兴。
答案 8 :(得分:-3)
您可以在一分钟内将测试更改为TestNg测试(您只需要更改导入),TestNG是并行测试中最好的。
答案 9 :(得分:-3)
您可以尝试Gridgain,让您在计算网格中运行分发测试。