【发布时间】:2016-01-18 15:01:17
【问题描述】:
在我的 JUnit 测试中,我想执行并行测试。
我的初稿不行:
@Test
public void parallelTestNotOk() {
ExecutorService executor = Executors.newFixedThreadPool(10);
Runnable testcaseNotOk = () -> fail("This failure is not raised.");
IntStream.range(0, 20).forEach(i -> executor.submit(testcaseNotOk));
executor.shutdown();
}
虽然每个testcaseNotOk 都失败了,但这个测试用例成功了。为什么?因为fail不是在主线程中调用的,而是在并行线程中调用的?
我的第二稿有效,因为这个测试用例按预期失败:
@Test
public void parallelTestOk() throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(10);
Callable<AssertionError> testcaseOk = () -> {
try {
fail("This failure will be raised.");
} catch (AssertionError e) {
return e;
}
return null;
};
List<Callable<AssertionError>> parallelTests = IntStream
.range(0, 20).mapToObj(i -> testcaseOk)
.collect(Collectors.toList());
List<AssertionError> allThrownAssertionErrors = executor.invokeAll(parallelTests)
.stream().map(future -> {
try {
return future.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}).filter(assertionError -> assertionError != null).collect(Collectors.toList());
executor.shutdown();
for (AssertionError e : allThrownAssertionErrors) {
throw e;
}
}
以下内容已完成:
- 在
testcaseOk中,要测试的代码嵌入到 try/catch 块中,并且每个AssertionError都会重新抛出。 -
parallelTests包含 20 次testcaseOk。 -
ExecutorService执行所有parallelTests。 - 如果在
testcaseOk中抛出AssertionError,它将被收集到allThrownAssertionErrors。 - 如果
allThrownAssertionErrors包含任何AssertionError,它将被抛出并且测试用例parallelTestOk()将失败。否则就OK了。
我的parallelTestOk() 似乎很复杂。有没有更简单、更智能的方法(不使用 TestNG)?
【问题讨论】:
-
建议的副本已过时,因为自 4.7 以来 JUnit 已包含一个并行运行器(可轻松用于 Maven 和 Gradle)。
标签: java multithreading junit