@Before、@BeforeClass、@BeforeEach和@BeforeAll的区别

516

在JUnit 4中,@Before@BeforeClass的主要区别是:

  • @Before用于在每个测试方法之前执行,这些方法可能需要相同的对象进行初始化。
  • @BeforeClass在所有测试方法之前只执行一次,通常用于创建共享的资源(例如数据库连接等)。

而在JUnit 5中,@BeforeEach@BeforeAll与此类似。

根据JUnit Api文档,@Before的作用是:

在编写测试时,通常会发现多个测试需要在运行之前创建相似的对象。

相比之下,@BeforeClass可用于建立数据库连接等。但是,@Before也可以完成同样的任务吗?

7个回答

744

被标记为@Before的代码在每个测试之前执行,而@BeforeClass则在整个测试夹具之前运行一次。如果您的测试类有十个测试,@Before代码将被执行十次,但@BeforeClass只会被执行一次。

通常,当多个测试需要共享相同的计算密集型设置代码时,您可以使用@BeforeClass。建立数据库连接属于此类别。您可以将@BeforeClass中的代码移动到@Before中,但测试运行时间可能会更长。请注意,标记为@BeforeClass的代码是作为静态初始化器运行的,因此它将在创建测试夹具的类实例之前运行。

JUnit 5中,@BeforeEach@BeforeAll 标签分别是 JUnit 4 中 @Before@BeforeClass 的等效标签。它们的名称更能指示它们的运行时间,大致解释为“每次测试之前”和“所有测试之前仅一次”。


9
@BeforeClass是静态的,在创建测试类实例之前运行。 - Sergey Kalinichenko
2
请记住,当您使用@BeforeClass时,您的方法/参数需要是静态的。 - tiagocarvalho92
虽然这不是直接相关的,但这是一种计算“按类别测试”的计数器的方法。 - Bsquare ℬℬ
我只想补充一点,@BeforeAll 可能是非静态的,并且在每次新的测试实例运行时调用。请参见相应的答案 https://dev59.com/xlMI5IYBdhLWcg3wn9D6#55720750。 - Sergey
@fireball.1 我也遇到了同样的问题。 - shiva
显示剩余2条评论

172

每种注释之间的区别是:

+-------------------------------------------------------------------------------------------------------+
¦                                       Feature                            ¦   Junit 4    ¦   Junit 5   ¦
¦--------------------------------------------------------------------------+--------------+-------------¦
¦ Execute before all test methods of the class are executed.               ¦ @BeforeClass ¦ @BeforeAll  ¦
¦ Used with static method.                                                 ¦              ¦             ¦
¦ For example, This method could contain some initialization code          ¦              ¦             ¦
¦-------------------------------------------------------------------------------------------------------¦
¦ Execute after all test methods in the current class.                     ¦ @AfterClass  ¦ @AfterAll   ¦
¦ Used with static method.                                                 ¦              ¦             ¦
¦ For example, This method could contain some cleanup code.                ¦              ¦             ¦
¦-------------------------------------------------------------------------------------------------------¦
¦ Execute before each test method.                                         ¦ @Before      ¦ @BeforeEach ¦
¦ Used with non-static method.                                             ¦              ¦             ¦
¦ For example, to reinitialize some class attributes used by the methods.  ¦              ¦             ¦
¦-------------------------------------------------------------------------------------------------------¦
¦ Execute after each test method.                                          ¦ @After       ¦ @AfterEach  ¦
¦ Used with non-static method.                                             ¦              ¦             ¦
¦ For example, to roll back database modifications.                        ¦              ¦             ¦
+-------------------------------------------------------------------------------------------------------+

两个版本中的大多数注释相同,但有一些不同。

参考链接

执行顺序。

虚线框 -> 可选注释。

enter image description here


18

Junit中的Before和BeforeClass

@Before注解所标记的函数会在拥有@Test注解的类中每个测试函数执行前被调用,而具有@BeforeClass注解的函数只会在该类中所有测试函数之前被调用一次。

同样地,带有@After注解的函数会在拥有@Test注解的类中每个测试函数执行后被调用,而具有@AfterClass注解的函数只会在该类中所有测试函数结束后被调用一次。

示例类

public class SampleClass {
    public String initializeData(){
        return "Initialize";
    }

    public String processDate(){
        return "Process";
    }
 }

示例测试

public class SampleTest {

    private SampleClass sampleClass;

    @BeforeClass
    public static void beforeClassFunction(){
        System.out.println("Before Class");
    }

    @Before
    public void beforeFunction(){
        sampleClass=new SampleClass();
        System.out.println("Before Function");
    }

    @After
    public void afterFunction(){
        System.out.println("After Function");
    }

    @AfterClass
    public static void afterClassFunction(){
        System.out.println("After Class");
    }

    @Test
    public void initializeTest(){
        Assert.assertEquals("Initailization check", "Initialize", sampleClass.initializeData() );
    }

    @Test
    public void processTest(){
        Assert.assertEquals("Process check", "Process", sampleClass.processDate() );
    }

}

输出

Before Class
Before Function
After Function
Before Function
After Function
After Class

在 Junit 5 中

@Before = @BeforeEach
@BeforeClass = @BeforeAll
@After = @AfterEach
@AfterClass = @AfterAll

10

JUnit @BeforeEach、@AfterEach、@BeforeAll 和 @AfterAll

@Before(JUnit4) -> @BeforeEach(JUnit5)- 在每次测试之前调用该方法。

@After(JUnit4) -> @AfterEach(JUnit5)- 在每次测试之后调用该方法。

@BeforeClass(JUnit4) -> @BeforeAll(JUnit5)- 调用一个静态方法,该方法在执行类中的所有测试之前被调用。它可以是一项较大的任务,例如启动服务器、读取文件或进行数据库连接...

@AfterClass(JUnit4) -> @AfterAll(JUnit5)- 调用一个静态方法,在执行类中的所有测试之后被调用。


2
import org.junit.Assert
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test

class FeatureTest {
    companion object {
        private lateinit var heavyFeature: HeavyFeature
        @BeforeClass
        @JvmStatic
        fun beforeHeavy() {
            heavyFeature = HeavyFeature()
        }
    }

    private lateinit var feature: Feature

    @Before
    fun before() {
        feature = Feature()
    }

    @Test
    fun testCool() {
        Assert.assertTrue(heavyFeature.cool())
        Assert.assertTrue(feature.cool())
    }

    @Test
    fun testWow() {
        Assert.assertTrue(heavyFeature.wow())
        Assert.assertTrue(feature.wow())
    }
}

Same as

import org.junit.Assert
import org.junit.Test

 class FeatureTest {
    companion object {
        private val heavyFeature = HeavyFeature()
    }

    private val feature = Feature()

    @Test
    fun testCool() {
        Assert.assertTrue(heavyFeature.cool())
        Assert.assertTrue(feature.cool())
    }

    @Test
    fun testWow() {
        Assert.assertTrue(heavyFeature.wow())
        Assert.assertTrue(feature.wow())
    }
}

1
所有这些注解的基本区别如下:
  1. @BeforeEach - 在每个测试方法执行之前运行公共代码(例如setUp),类似于JUnit 4的@Before。
  2. @AfterEach - 在每个测试方法执行后运行公共代码(例如tearDown),类似于JUnit 4的@After。
  3. @BeforeAll - 在任何测试执行之前,每个类只运行一次。类似于JUnit 4的@BeforeClass。
  4. @AfterAll - 在所有测试执行完成后,每个类只运行一次。类似于JUnit 4的@AfterClass。
所有这些注解以及使用方法都在Codingeek - Junit5 Test Lifecycle中定义。

0

@BeforeClass 会在整个测试套件之前运行,而@Before会在每个测试执行之前执行,@BeforeClass则是在整个测试夹具之前仅运行一次。如果您的测试类有十个测试,则@Before代码将被执行十次,但只有@BeforeClass将被执行一次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接