我尝试使用main()
方法运行junit:
public static void main(String... args) throws ClassNotFoundException,
IOException {
//...
logger.debug("className " + className + "methodName " + methodName);
Request request = Request.method(Class.forName(className), methodName);
return new JUnitCore().run(request);
}
我有一个带有10个命令的E2E测试(比方说)。它由JUnit运行,我想将命令3-5的运行时间限制为 X millis(其中 X 在运行时确定)。如果它的运行时间超过 X ,我想返回main()
并打印一些内容。
我尝试了System.exit()
,但它关闭了整个应用程序。我试过了:
public void setTimeOut(String criticalBlockTimeOutMilli) {
if (criticalBlockTimeOutMilli != null) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
E2eResult e2eResult = E2eResult.getInstance();
e2eResult.status = E2eStatus.TIMEOUT;
//System.exit(2);
}
};
new Timer().schedule(timerTask, Long.parseLong(criticalBlockTimeOutMilli));
}
}
public void setTimeOut(final Thread thread, String criticalBlockTimeOutMilli) {
if (criticalBlockTimeOutMilli != null) {
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
E2eResult e2eResult = E2eResult.getInstance();
e2eResult.status = E2eStatus.TIMEOUT;
thread.interrupt();
}
};
new Timer().schedule(timerTask, Long.parseLong(criticalBlockTimeOutMilli));
}
}
但即使超出限制,主线程仍会继续运行测试。你会建议什么?
答案 0 :(得分:1)
单元测试可能不是解决此类性能测试的最佳方法。但是,如果出于某种原因必须这样做,请继续阅读......
使用ExecutorService
以给定的超时运行所需的命令。如果超时到期,抛出你自己的异常,你可以在主线程中捕获:
@Test
public void yourTest() throws Exception {
// Do commands 1-2
ExecutorService service = Executors.newSingleThreadExecutor();
Future<Void> result = service.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
// call commands 3-5
return null;
}
});
try {
result.get(42, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
throw new YourOwnException();
}
service.shutdown();
// Do commands 6-10
}
答案 1 :(得分:1)
一个相当简单的机制是使用BlockingQueue
来表示测试已完成。如果您发现它没有,那么您可以interrupt
它。这仅在测试正确响应被中断时才有效。
// Send FINISHED down this queue when test completes.
final BlockingQueue<Object> finished = new ArrayBlockingQueue<>(1);
// FINISHED cookie.
static final Object FINISHED = new Object();
public void test() throws InterruptedException {
Thread test = new Thread(new Runnable() {
@Override
public void run() {
// Do your stuff.
// ...
// Signal we finished.
finished.add(FINISHED);
}
});
// Start the test in it's own thread.
test.start();
try {
// Wait for your time.
if (FINISHED == finished.poll(5, TimeUnit.MILLISECONDS)) {
// It completed! No problems.
} else {
// It hasn't finished! Interrupt it.
test.interrupt();
};
} catch (InterruptedException ex) {
// We were interrupted! Do something.
test.interrupt();
// Rethrow it.
throw(ex);
}
}
您可以通过添加&#34;已启动&#34;来扩展此机制。消息也是如此,以确保测试线程至少有机会运行。