Różnica między @Before, @BeforeClass, @BeforeEach i @BeforeAll

432

Jaka jest główna różnica między

  • @Before i @BeforeClass
    • oraz w JUnit 5 @BeforeEachi@BeforeAll
  • @After i @AfterClass

Według JUnit Api @Before jest używany w następującym przypadku:

Podczas pisania testów często zdarza się, że kilka testów wymaga podobnych obiektów utworzonych przed ich uruchomieniem.

@BeforeClassMożna natomiast użyć do nawiązania połączenia z bazą danych. Ale czy nie mógł @Beforezrobić tego samego?

użytkownik1170330
źródło

Odpowiedzi:

623

Oznaczony kod @Beforejest wykonywany przed każdym testem, a @BeforeClassuruchamia się raz przed całym urządzeniem testowym. Jeśli klasa testowa ma dziesięć testów, @Beforekod zostanie wykonany dziesięć razy, ale @BeforeClasszostanie wykonany tylko raz.

Zasadniczo używa się go, @BeforeClassgdy wiele testów wymaga współużytkowania tego samego kosztownego obliczeniowo kodu instalacyjnego. Nawiązanie połączenia z bazą danych należy do tej kategorii. Można przenieść kod @BeforeClassdo @Before, ale twój test nie może trwać dłużej. Zauważ, że zaznaczony kod @BeforeClassjest uruchamiany jako inicjator statyczny, dlatego będzie działał przed utworzeniem instancji klasy urządzenia testowego.

W JUnit 5 tagi@BeforeEach i @BeforeAllsą ekwiwalentów @Beforeoraz @BeforeClassw JUnit 4. Ich nazwy są nieco bardziej wskazuje kiedy biegać, luźno interpretować: „przed każdym testów” i „kiedyś wszystkich testów”.

dasblinkenlight
źródło
4
Ach, teraz przykład z połączeniem DB ma sens. Dziękuję Ci!
user1170330,
6
@pacoverflow @BeforeClasjest statyczny. Działa przed utworzeniem instancji klasy testowej.
dasblinkenlight
1
Pamiętaj, że gdy używasz @BeforeClass, twoja metoda / parametr musi być statyczny
tiagocarvalho92
Nie jest to bezpośrednio powiązane, ale jest to sposób na obliczenie licznika „Testy według kategorii” .
Bsquare
Dodam tylko, że @BeforeAllmogą być niestatyczne i wzywam przy każdym nowym uruchomieniu instancji testowej. Zobacz odpowiednią odpowiedź stackoverflow.com/a/55720750/1477873
Sergey
124

Różnice między każdą adnotacją są następujące:

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

Większość adnotacji w obu wersjach jest taka sama, ale niewiele się różni.

Odniesienie

Kolejność wykonania.

Pole przerywane -> opcjonalna adnotacja.

wprowadź opis zdjęcia tutaj

Joby Wilson Mathews
źródło
10

Before and BeforeClass w JUnit

@BeforeAdnotacja funkcji zostanie wykonana przed każdą funkcją testową w klasie posiadającej @Testadnotację, ale funkcja z @BeforeClasszostanie wykonana tylko jeden raz przed wszystkimi funkcjami testowymi w klasie.

Podobnie funkcja z @Afteradnotacją zostanie wykonana po każdej funkcji testowej w klasie posiadającej @Testadnotację, ale funkcja z@AfterClass zostanie wykonana tylko raz po wszystkich funkcjach testowych w klasie.

SampleClass

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

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

Próbny test

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

}

Wynik

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

W Junit 5

@Before = @BeforeEach
@BeforeClass = @BeforeAll
@After = @AfterEach
@AfterClass = @AfterAll
Dhyan Mohandas
źródło
1
Bardzo dobry przykład.
kanaparthikiran
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())
    }
}

Taki sam jak

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())
    }
}
kreker
źródło