关于java:@ Before,@ BeforeClass,@ BeforeEach和@BeforeAll之间的区别

Difference between @Before, @BeforeClass, @BeforeEach and @BeforeAll

之间的主要区别是什么

  • @Before@BeforeClass

    • 在JUnit 5 @BeforeEach@BeforeAll
  • @After@AfterClass

根据JUnit,在以下情况下使用Api @Before

When writing tests, it is common to find that several tests need similar objects created before they can run.

@BeforeClass可用于建立数据库连接。 但是@Before不能做同样的事情吗?


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

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

在JUnit 5中,标记@BeforeEach@BeforeAll与JUnit 4中的@Before@BeforeClass等效。它们的名称更能指示它们的运行时间,并可以轻松地解释为:"在每次测试之前"和"在所有测试之前进行一次。


每个注释之间的区别是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+-------------------------------------------------------------------------------------------------------+
|                                       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


JUnit中的BeforeClass和BeforeClass

函数@Before批注将在具有@Test批注的类中的每个测试函数之前执行,而带有@BeforeClass的函数仅在类中的所有测试函数之前执行一次。

类似地,具有@After注释的函数将在具有@Test注释的类中的每个测试函数之后执行,而具有@AfterClass的函数将仅在该类中的所有测试函数之后执行一次。

SampleClass

1
2
3
4
5
6
7
8
9
public class SampleClass {
    public String initializeData(){
        return"Initialize";
    }

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

SampleTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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() );
    }

}

产量

1
2
3
4
5
6
Before Class
Before Function
After Function
Before Function
After Function
After Class

在Junit 5中

1
2
3
4
@Before = @BeforeEach
@BeforeClass = @BeforeAll
@After = @AfterEach
@AfterClass = @AfterAll


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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())
    }
}

如同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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())
    }
}