实际上,超时规则将相同的超时应用于类中的所有测试方法。
如果不想将其添加到每个 Test 类,可以在测试基类中定义一次。
对于不需要更改所有类的内容,您可以实现 Junit 自定义套件运行器( 请参阅第二个代码示例 )
只是为了好玩,使用已弃用的Thread.stop方法这个黑客解决方案怎么样?
在函数启动之前,每个测试都有一个观察程序线程,在超时之后会终止 Junit 测试线程。
如果测试完成,清理将终止观察程序线程。
适用于这个小演示,不确定这是否适用于生产规模。
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
// You could also make this a base class for test classes
public class TimeoutTest {
Thread watcherThread ;
Thread junitTestThread;
final static int testTimeout = 2000;
@Before
public void myInit()
{
junitTestThread = Thread.currentThread();
watcherThread = new Thread()
{
@Override
public void run()
{
try {
Thread.sleep(testTimeout);
junitTestThread.stop();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
watcherThread.start();
}
@After
public void myCleanup() throws InterruptedException
{
watcherThread.stop();
}
@Test
public void testPassingFastTest() throws InterruptedException {
Thread.sleep(1000);
}
@Test
public void testFailingSlowTest() throws InterruptedException {
Thread.sleep(3000);
}
}
或者,对于使用套件的多个测试类执行此操作:
import java.util.Arrays;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
@RunWith(AllTests.class)
public class AllTests extends Suite{
Thread watcherThread ;
Thread junitTestThread;
final static int testTimeout = 70;
public AllTests(final Class<?> clazz) throws InitializationError {
super(clazz, findClasses());
}
private static Class<?>[] findClasses() {
// You could write code here to get the list of all test classes from specific directories
return new Class<?>[] {TimeoutTest.class,TimeoutTest2.class};
}
@Override
public void run(final RunNotifier notifier) {
notifier.addListener(new RunListener() {
@Override
public void testStarted(final Description description) {
System.out.println("Before test " + description.getDisplayName());
junitTestThread = Thread.currentThread();
watcherThread = new Thread()
{
@Override
public void run()
{
try {
Thread.sleep(testTimeout);
junitTestThread.stop();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
watcherThread.start();
}
@Override
public void testFinished(final Description description) {
System.out.println("After test " + description.getDisplayName());
watcherThread.stop();
}
}
);
super.run(notifier);
}
}