Разница между @Before, @BeforeClass, @BeforeEach и @BeforeAll

432

В чем главное отличие

  • @Before а также @BeforeClass
    • и в Юнит 5 @BeforeEachи@BeforeAll
  • @After а также @AfterClass

Согласно JUnit Api @Before используется в следующем случае:

При написании тестов часто обнаруживается, что нескольким тестам нужны похожие объекты, созданные до того, как они смогут работать.

Принимая во внимание, что @BeforeClassможет использоваться для установления соединения с базой данных. Но не мог @Beforeсделать то же самое?

user1170330
источник

Ответы:

624

Помеченный код @Beforeвыполняется перед каждым тестом, а @BeforeClassвыполняется один раз перед всем тестовым прибором. Если ваш тестовый класс имеет десять тестов, @Beforeкод будет выполнен десять раз, но @BeforeClassбудет выполнен только один раз.

Как правило, вы используете, @BeforeClassкогда несколько тестов должны использовать один и тот же дорогостоящий код установки. Установление соединения с базой данных попадает в эту категорию. Вы можете переместить код из @BeforeClassв @Before, но ваш тестовый запуск может занять больше времени. Обратите внимание, что помеченный код @BeforeClassзапускается как статический инициализатор, поэтому он будет выполняться до создания экземпляра класса вашего тестового устройства.

В JUnit 5 теги @BeforeEachи @BeforeAllявляются эквивалентами @Beforeи @BeforeClassв JUnit 4. Их имена немного более показательны, когда они выполняются, в некоторой степени интерпретируются: «перед каждым тестом» и «один раз перед всеми тестами».

dasblinkenlight
источник
4
Ах, теперь пример с подключением к БД имеет смысл. Спасибо!
user1170330
6
@pacoverflow @BeforeClasявляется статическим. Он запускается до создания экземпляров тестового класса.
dasblinkenlight
1
Помните, что когда вы используете @BeforeClass, ваш метод / параметр должен быть статическим
tiagocarvalho92
Он не имеет прямого отношения, но это способ вычисления счетчика «Тесты по категориям» .
Квадрат ℬℬ
Я добавлю только то, что @BeforeAllможет быть нестатичным и вызывать при каждом новом запуске тестового экземпляра. См. Соответствующий ответ stackoverflow.com/a/55720750/1477873
Сергей
124

Разница между каждой аннотацией:

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

Большинство аннотаций в обеих версиях одинаковы, но мало отличаются.

Ссылка

Порядок исполнения.

Штриховая рамка -> дополнительная аннотация.

введите описание изображения здесь

Джоби Уилсон Мэтьюз
источник
10

До и Перед Классом в JUnit

@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
Дхиан Мохандас
источник
1
Очень хороший пример.
Канапартикиран
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())
    }
}

Такой же как

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())
    }
}
Крекер
источник