在我的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
。AssertionError
中出现testcaseOk
,则会将其收集到allThrownAssertionErrors
。allThrownAssertionErrors
包含任何AssertionError
,则会抛出它,并且测试用例parallelTestOk()
将失败。否则就可以了。我的parallelTestOk()
似乎相当复杂。是否有更简单,更智能的方式(不使用TestNG)?
答案 0 :(得分:2)
您的问题是您从不检查Future
中的值以查看是否抛出了异常。
这将使测试正确失败:
@Test
public void parallelTestWillFail() throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(10);
Runnable testcaseNotOk = () -> fail("This failure IS raised.");
List<Future<?>> futures = IntStream.range(0, 20)
.mapToObj(i -> executor.submit(testcaseNotOk))
.collect(Collectors.toList());
executor.shutdown();
for(Future<?> f : futures){
f.get();
}
}