繁体   English   中英

在所有JUnit测试之后清除,而无需显式测试套件类声明

[英]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...

所需的行为是:

  1. 右键点击
  2. 运行所有测试
  3. TestA正在运行...
  4. 测试完成
  5. TestB正在运行...
  6. TestB完成
  7. ...更多测试课程...
  8. 清理

不确定我是否完全正确地回答了您的问题,但是我认为您想要使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM