[英]Cleaning up after all JUnit tests without explicit test suite classes declaration
在Intelij和Eclipse IDE(可能还有其他一些IDE)中,可以从包中运行所有测试类(甚至项目中的所有测试类),而无需将每个测试类显式地放在测试套件类中( 这是某些事情)我想避免)。 只需右键单击->运行所有测试即可!
不过,这种测试方法存在一个问题。 在完成所有测试后,我想进行一些清理,但是无论我做什么,似乎都无济于事。
最初,我尝试使用RunListener及其testRunFinished()方法,但是在每次原子测试完成后都会调用它,因此在运行许多原子测试时不是我想要的。
然后,我想到了finalizer和runFinalizersOnExit(true) ,不幸的是,它已被弃用,并且仅在执行测试的计算机上工作。
我最后尝试做的是创建一个“侦听器”线程,给定测试执行的开始时间和结束时间的差异,该线程将在测试完成五秒钟后清理。 我使用下面的代码来测试该解决方案:
import org.junit.Test;
public class Main {
static {
System.out.println("In a static block!");
new Thread(new Runnable() {
public void run() {
System.out.println("Starting static thread!");
try {
while (true) {
Thread.sleep(1000);
System.out.println("Static thread working...");
}
} catch (InterruptedException e) {
System.err.println("Static thread interrupted!");
e.printStackTrace();
} catch (Exception e) {
System.err.println("Static thread catches exception!");
e.printStackTrace();
} finally {
System.err.println("Static thread in finally method.");
Thread.currentThread().interrupt();
}
}
}).start();
System.out.println("Exiting static block!");
}
@Test
public void test() throws Exception {
System.out.println("Running test!");
Thread.sleep(3000);
System.out.println("Stopping test!");
}
}
没有运气。 测试完成后,线程将被杀死。 甚至finally块也永远不会执行...
In a static block!
Exiting static block!
Running test!
Starting static thread!
Static thread working...
Static thread working...
Stopping test!
Static thread working...
所需的行为是:
不确定我是否完全正确地回答了您的问题,但是我认为您想要使用before,beforeClass,after和afterClass方法。 即
@BeforeClass
public void beforeClass() {
// Do stuff before test class is run
}
@Before
public void before() {
// Do stuff before each test is run
}
@After
public void after() {
// DO stuff after each test is run
}
@AfterClass
public void afterClass() {
// DO stuff after test class is run
}
您可以使用某些黑客或其他框架在更全球化的水平上做事。 以Spring的测试套件为例。 但是我会尽量将这些东西放在单个测试类的范围内。
我已经找到解决问题的办法。 我的同事建议“嘿,您难道不能只计算考试人数吗?” -那就是我所做的。
这里使用了一些反射魔术,因此代码可能无法移植:
public abstract class CleaningTestRunner extends BlockJUnit4ClassRunner {
protected abstract void cleanupAfterAllTestRuns();
private static long TEST_CLASSES_AMOUNT;
private static long TEST_RUNS_FINISHED = 0;
private static boolean CLASSES_COUNTED = false;
static {
while (!CLASSES_COUNTED) {
try {
Field f = ClassLoader.class.getDeclaredField("classes");
f.setAccessible(true);
Vector<Class> classes = (Vector<Class>) f.get(CleaningTestRunner.class.getClassLoader());
TEST_CLASSES_AMOUNT = 0;
for (Class<?> klass : classes) {
if (klass.isAnnotationPresent(RunWith.class)) {
if (CleaningTestRunner.class.isAssignableFrom(klass.getAnnotation(RunWith.class).value())) {
for (Method method : klass.getMethods()) {
if (method.isAnnotationPresent(Test.class)) {
++TEST_CLASSES_AMOUNT;
break;
}
}
}
}
}
CLASSES_COUNTED = true;
} catch (Exception ignored) {
}
}
}
public CleaningTestRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
public void run(RunNotifier notifier) {
notifier.addListener(new TestCleanupListener());
super.run(notifier);
}
private class TestCleanupListener extends RunListener {
@Override
public void testRunFinished(Result result) throws Exception {
++TEST_RUNS_FINISHED;
if (TEST_RUNS_FINISHED == TEST_CLASSES_AMOUNT) {
cleanupAfterAllTestRuns();
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.