如何在多个测试类之间共享JUnit BeforeClass逻辑

当前,我所有的JUnit测试都从一个通用的基类扩展而来,该基类提供了带有@BeforeClass和标记的方法

@AfterClass-真正要做的就是设置一堆静态资源/服务以供测试使用。

由于某些原因,这对我来说似乎很尴尬:

  1. 根据我的理解,JUnit4的部分要点是我们不再需要这种经典的测试继承。
  2. 当我将这些测试作为套件的一部分而不是单独运行(我们经常这样做)时,多次调用@BeforeClass@AfterClass,从而减慢了测试的速度-我们实际上应该只调用一次

我想做的是以某种方式将当前的BeforeClass / AfterClass逻辑移出继承链,并移到可以由单个测试和整个套件共享的东西中。

(如果有关系,我正在使用JUnit 4.7,将其更新为其他版本可能会很困难)

回答:

第一个问题的解决方案是org.junit.rules.ExternalResource通过@ClassRuleJUnit

4.9中引入的,将逻辑移到与测试挂钩的扩展中:

public class MyTest {

@ClassRule

public static final TestResources res = new TestResources();

@Test

public void testFoo() {

// test logic here

}

}

public class TestResources extends ExternalResource {

protected void before() {

// Setup logic that used to be in @BeforeClass

}

protected void after() {

// Setup logic that used to be in @AfterClass

}

}

这样,以前由基类管理的资源将移出测试类层次结构,并移入更多的模块化/可使用的“资源”,这些资源可以在类运行之前创建,而在类运行之后销毁。

至于同时解决两个问题-即:作为单个测试的一部分和作为套件的一部分,具有相同的高级设置/拆卸运行-似乎对此没有任何特定的内置支持。 。 ,

您可以自己实现

只需将@ClassRule资源创建更改为工厂模式,该模式会在内部进行引用计数,以确定是否创建/销毁资源。

例如(请注意,这很粗糙,可能需要一些调整/错误处理才能确保其健壮性):

public class TestResources extends ExternalResource {

private static int refCount = 0;

private static TestResources currentInstance;

public static TestResources getTestResources () {

if (refCount == 0) {

// currentInstance either hasn't been created yet, or after was called on it - create a new one

currentInstance = new TestResources();

}

return currentInstance;

}

private TestResources() {

System.out.println("TestResources construction");

// setup any instance vars

}

protected void before() {

System.out.println("TestResources before");

try {

if (refCount == 0) {

System.out.println("Do actual TestResources init");

}

}

finally {

refCount++;

}

}

protected void after() {

System.out.println("TestResources after");

refCount--;

if (refCount == 0) {

System.out.println("Do actual TestResources destroy");

}

}

}

您的套件/测试类都将@ClassResource通过工厂方法使用资源:

@RunWith(Suite.class)

@SuiteClasses({FooTest.class, BarTest.class})

public class MySuite {

@ClassRule

public static TestResources res = TestResources.getTestResources();

@BeforeClass

public static void suiteSetup() {

System.out.println("Suite setup");

}

@AfterClass

public static void suiteTeardown() {

System.out.println("Suite teardown");

}

}

public class FooTest {

@ClassRule

public static TestResources res = TestResources.getTestResources();

@Test

public void testFoo() {

System.out.println("testFoo");

}

}

public class BarTest {

@ClassRule

public static TestResources res = TestResources.getTestResources();

@Test

public void testBar() {

System.out.println("testBar");

}

}

在运行单个测试时,重新引用不会有任何效果-“实际初始化”和“实际拆卸”将只发生一次。在套件中运行时,套件将创建TestResource,而各个测试将仅重用已实例化的TestResource(引用计数使它不会在套件中的测试之间被实际破坏和重新创建)。

以上是 如何在多个测试类之间共享JUnit BeforeClass逻辑 的全部内容, 来源链接: utcz.com/qa/403198.html

回到顶部