我想停下来并标记为失败太长时间运行junit测试(在Maven 3版本中执行).我知道有三种方法:
1)使用带有超时参数的Test注释:
@Test(timeout=100)
public void testWithTimeout() {
...
}
Run Code Online (Sandbox Code Playgroud)
2)使用规则注释:
@Rule
public Timeout globalTimeout = new Timeout(100);
Run Code Online (Sandbox Code Playgroud)
3)使用以下选项配置maven-surefire-plugin:
forkedProcessTimeoutInSeconds=1
reuseForks=false
Run Code Online (Sandbox Code Playgroud)
线索是1)和2)需要改变每个测试(当你有成千上万时它会受到伤害).3)解决方案是不可接受的,因为在许多模块中,首先测试开始测试所使用的上下文 - 测试性能将急剧下降.
你有任何其他想法如何实现吗?任何棘手的解决方案(不涉及修补JUnit :))?
实际上,超时规则对类中的所有测试方法应用相同的超时。
如果您不想将其添加到每个 Test 类中,则可以在 Test 基类中定义一次。
对于不需要更改所有类的东西,您可以实现 Junit 自定义套件运行程序(请参阅第二个代码示例)
只是为了好玩,这个使用已弃用的 Thread.stop 方法的黑客解决方案怎么样?
Before 函数为每个测试启动一个观察线程,超时后会终止 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);
}
}
Run Code Online (Sandbox Code Playgroud)
或者使用套件对多个测试类执行此操作:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1495 次 |
| 最近记录: |