【问题标题】:Difference between @Before, @BeforeClass, @BeforeEach and @BeforeAll@Before、@BeforeClass、@BeforeEach 和 @BeforeAll 之间的区别
【发布时间】:2023-03-24 16:01:01
【问题描述】:

两者的主要区别是什么

  • @Before@BeforeClass
    • 在 JUnit 5 中 @BeforeEach@BeforeAll
  • @After@AfterClass

根据JUnit Api@Before用于以下情况:

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

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

【问题讨论】:

    标签: java junit annotations junit4 junit5


    【解决方案1】:

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

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

    JUnit 5 中,标签@BeforeEach@BeforeAll 等效于JUnit 4 中的@Before@BeforeClass。它们的名称更能说明它们的运行时间,松散地解释为:'在每个之前测试”和“所有测试前一次”。

    【讨论】:

    • @pacoverflow @BeforeClas 是静态的。它在创建测试类实例之前运行。
    • 请记住,当您使用 @BeforeClass 时,您的方法/参数需要是静态的
    • 没有直接关系,但这是compute 'Tests by Category' counter的一种方式。
    • 我只会补充一点,@BeforeAll 可能是非静态的,并且会在每次新的测试实例运行时调用。查看对应答案stackoverflow.com/a/55720750/1477873
    • 你确定BeforeBeforeEach 是一样的吗,因为当我在init() 函数上使用@Before 但与@BeforeEach 一起使用时,我的测试用例失败了模拟
    【解决方案2】:

    每个注释之间的区别是:

    +-------------------------------------------------------------------------------------------------------+
    ¦                                       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.                        ¦              ¦             ¦
    +-------------------------------------------------------------------------------------------------------+
    

    两个版本中的大多数注释都是相同的,但很少有不同。

    Reference

    执行顺序。

    虚线框 -> 可选注释。

    【讨论】:

      【解决方案3】:

      JUnit 中的Before 和BeforeClass

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

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

      SampleClass

      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
      

      在六月 5

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

      【讨论】:

        【解决方案4】:
        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())
            }
        }
        

        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())
            }
        }
        

        【讨论】:

          【解决方案5】:

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

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

          @BeforeClass(JUnit4) -> @BeforeAll(JUnit5) - 静态方法在执行该类中的所有测试之前调用。启动服务器、读取文件、建立数据库连接可能是一项大任务......

          @AfterClass(JUnit4) -> @AfterAll(JUnit5) - 静态方法在执行完该类中的所有测试后调用。

          【讨论】:

            【解决方案6】:

            所有这些注解的基本区别如下——

            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上定义

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                猜你喜欢
                • 2014-02-20
                • 1970-01-01
                • 2015-08-15
                • 2019-11-02
                • 1970-01-01
                • 1970-01-01
                • 2011-11-11
                • 2012-05-20
                • 1970-01-01
                相关资源
                最近更新 更多