【问题标题】:How to run a set of code before and after any tests in any class?如何在任何类的任何测试之前和之后运行一组代码?
【发布时间】:2014-10-13 14:52:56
【问题描述】:

这是我的测试代码:

public class Test1 {
    @BeforeClass
    public void setUp() {
        EmbeddedTomcat.start();
    }

    // test methods...

    @AfterClass
    public void tearDown() {
        EmbeddedTomcat.stop();
    }      
}

public class Test2 {
    @BeforeClass
    public void setUp() {
        EmbeddedTomcat.start();
    }

    // test methods...

    @AfterClass
    public void tearDown() {
        EmbeddedTomcat.stop();
    }
}

// ...

如您所见,我在每个 Test 类中复制了对嵌入式 tomcat 的启动和停止调用。如何避免与 JUnit 的这种重复?

要求: - 所有测试类的启动和停止调用必须调用一次

JUnit 4.11

【问题讨论】:

  • @wrongAnswer OP 使用 @BeforeClass@AfterClass 在所有测试执行之前和之后执行,而不是每次测试执行。

标签: java unit-testing junit initialization


【解决方案1】:

除了创建一个运行@BeforeClass@AfterClass 的父类。您可以创建一个 JUnit Rule。您可以将您的规则子类化为 ExternalResource,它具有可覆盖的方法,用于在执行(类或测试)之前和之后添加行为。

public class EmbeddedTomcatServer extends ExternalResource {

            ...

            @Override
            protected void before() throws Throwable {
                    EmbeddedTomcat.start();
            };

            @Override
            protected void after() {
                    EmbeddedTomcat.stop();
            };
    }

然后在您的测试中使用@ClassRule,它在BeforeClassAfterClass 时间运行服务器的before()after() 方法。

public class Test1 {

   @ClassRule
   public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();

   //tests as normal, no more @BeforeClass or @AfterClass

}

public class Test2 {

   @ClassRule
   public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();

   //tests as normal, no more @BeforeClass or @AfterClass

}

此解决方案可能比使用父类更好,因为您可以在任何测试中使用此规则,而无需更改父类。

编辑 只运行一次 start() 和 stop()

你的意思是不是每个测试类运行一次启动和停止有点不清楚(作为使用@BeforeClass 和@AfterClass 的原始代码)

或者,如果您想在所有运行的测试类中的所有测试中只运行一次启动和停止。

如果你想做后者,@ClassRules 在这里也很有帮助。只需创建一个包含要使用的测试类的测试套件,然后将 ClassRule 仅放在 SUITE 类中

@RunWith(Suite.class)
@SuiteClasses({ Test1.class, Test2.class })
public class AllTests {
   @ClassRule
   public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();

}

这将在 AllTests 套件启动时启动 tomcat,然后在测试套件中的所有测试都运行后停止 tomcat。

【讨论】:

  • EmbeddedTomcatServer 是什么? (枚举,类...)
  • @Stephan 这是一个类,对不起,我修复了上面的代码谢谢!
  • 现在出现错误:“该位置不允许使用注释@Rule”
  • 从 EmbededTomcatServer 类中删除 @Rule (如果该类在它自己的文件中,则去掉结尾的分号)。看起来规则 API 会随着时间而改变,因此您不再需要 @Rule。但仍将@ClassRule 放在测试类中
  • @Stephan 还添加了只运行一次启动和停止的答案
【解决方案2】:

如果您的项目可能,您可以创建一个 TestParent 类来定义这些 @BeforeClass@AfterClass 方法,并使您的 Test1Test2 类从它扩展。

public class TestParent {
    @BeforeClass
    public void setUp() {
        EmbeddedTomcat.start();
    }

    @AfterClass
    public void tearDown() {
        EmbeddedTomcat.stop();
    }    
}

public class Test1 extends TestParent {
    //...
}

public class Test2 extends TestParent {
    //...
}

【讨论】:

  • 我刚刚添加了一个新要求:setUptearDown 必须调用一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-19
  • 1970-01-01
  • 2012-01-23
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
相关资源
最近更新 更多