使用反射设置JUnit测试超时
问题描述:
迄今为止我发现了2种设置JUnit测试超时的方法。或者使用:使用反射设置JUnit测试超时
@Test(timeout=XXX)
或者使用类似:
@ClassRule
public static Timeout timeoutRule = new Timeout(XXX, TimeUnit.MILLISECONDS);
就我而言,我有一个测试运行的主类来运行我所有的测试套件,这样我就可以执行测试作为可执行的jar。 我希望这个跑步者使用反射来设置超时的超时时间。
可以吗?
答
您可以将超时功能添加到自定义测试运行,像这样:
public class TimeoutTestRunner extends BlockJUnit4ClassRunner {
public TimeoutTestRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
@Override
protected Statement withPotentialTimeout(FrameworkMethod method, Object test, Statement next) {
return FailOnTimeout.builder()
// you'll probably want to configure/inject this value rather than hardcode it ...
.withTimeout(1, TimeUnit.MILLISECONDS)
.build(next);
}
}
使用该测试运行在下面的测试案例的测试...
@RunWith(TimeoutTestRunner.class)
public class YourTest {
@Test
public void willTimeout() throws InterruptedException {
Thread.sleep(50);
assertTrue(true);
}
@Test
public void willNotTimeout() throws InterruptedException {
assertTrue(true);
}
}
...会表现如下:
-
willTimeout
:将失败,TestTimedOutException
-
willNotTimeout
:将通过
虽然你将需要你的测试通过这个亚军运行,你将能够控制自己的超时从一个地方设置和提供定制超时推导策略,如if test name matches <some regex> then timeout is x else ...
。
无法扩展BlockJUnit4ClassRunner,因为我的跑步者已经在扩展另一个类。 有没有其他办法可以做到这一点,而不必延长这一点? 可能会在类中插入一个新的超时字段,或者在运行时将测试注释的超时值插入... –
@AlexanderRumanovsk:我真的不认为您可以随时更改测试类。我认为一个定制的跑步者适合你的用例。你写道:“我的跑步者已经在扩展另一个类”,所以它必须(在层次结构的某个地方)扩展'org.junit.runner.Runner',所以如果一切都失败了(例如,如果你使用的跑步者没有一个简单的你可以总是覆盖'run()'方法,并且在超时块中将调用包装为'super.run()',它有一个'run()'方法。 – glytching