Unterschied zwischen @Before, @BeforeClass, @BeforeEach und @BeforeAll


432

Was ist der Hauptunterschied zwischen

  • @Before und @BeforeClass
    • und in JUnit 5 @BeforeEachund@BeforeAll
  • @After und @AfterClass

Laut JUnit wird Api @Before im folgenden Fall verwendet:

Beim Schreiben von Tests wird häufig festgestellt, dass für mehrere Tests ähnliche Objekte erstellt werden müssen, bevor sie ausgeführt werden können.

Während @BeforeClasskann eine Datenbankverbindung herzustellen verwendet werden. Aber konnte man das nicht @Beforeauch?

Antworten:


623

Der markierte Code @Beforewird vor jedem Test ausgeführt, während er @BeforeClasseinmal vor dem gesamten Testgerät ausgeführt wird. Wenn Ihre Testklasse zehn Tests enthält, wird der @BeforeCode zehnmal ausgeführt, jedoch @BeforeClassnur einmal.

Im Allgemeinen verwenden Sie diese Option, @BeforeClasswenn mehrere Tests denselben rechenintensiven Setup-Code verwenden müssen. Das Herstellen einer Datenbankverbindung fällt in diese Kategorie. Sie können Code von @BeforeClassin verschieben @Before, aber Ihr Testlauf kann länger dauern. Beachten Sie, dass der markierte Code @BeforeClassals statischer Initialisierer ausgeführt wird. Daher wird er ausgeführt, bevor die Klasseninstanz Ihres Testgeräts erstellt wird.

In JUnit 5 sind die Tags @BeforeEachund @BeforeAlldie Entsprechungen von @Beforeund @BeforeClassin JUnit 4. Ihre Namen geben etwas mehr Aufschluss darüber, wann sie ausgeführt werden, und werden lose interpretiert: "vor jedem Test" und "einmal vor allen Tests".


4
Ah, jetzt macht das Beispiel mit der DB-Verbindung Sinn. Vielen Dank!
user1170330

6
@pacoverflow @BeforeClasist statisch. Es wird ausgeführt, bevor Testklasseninstanzen erstellt werden.
Dasblinkenlight

1
Denken Sie daran, dass bei Verwendung von @BeforeClass Ihre Methode / Parameter statisch sein muss
tiagocarvalho92

Es ist nicht direkt verwandt, aber dies ist eine Möglichkeit, den Zähler "Tests nach Kategorie" zu berechnen .
Bsquare ℬℬ

Ich werde nur hinzufügen, dass dies @BeforeAllmöglicherweise nicht statisch ist, und bei jedem neuen Testinstanzlauf aufrufen. Siehe die entsprechende Antwort stackoverflow.com/a/55720750/1477873
Sergey

124

Der Unterschied zwischen den einzelnen Anmerkungen ist:

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

Die meisten Anmerkungen in beiden Versionen sind gleich, unterscheiden sich jedoch nur wenige.

Referenz

Ausführungsreihenfolge.

Gestricheltes Feld -> optionale Anmerkung.

Geben Sie hier die Bildbeschreibung ein


10

Before und BeforeClass in JUnit

Die Funktionsanmerkung @Beforewird vor jeder Testfunktion in der Klasse mit @TestAnmerkung ausgeführt, aber die Funktion mit @BeforeClasswird nur einmal vor allen Testfunktionen in der Klasse ausgeführt.

In ähnlicher Weise wird eine Funktion mit @AfterAnnotation nach jeder Testfunktion in der Klasse ausgeführt, die eine @TestAnnotation hat, aber die Funktion mit@AfterClass wird nur einmal nach allen Testfunktionen in der Klasse ausgeführt.

SampleClass

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

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

SampleTest

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

}

Ausgabe

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

In Junit 5

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

1
Sehr gutes Beispiel.
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())
    }
}

Gleich wie

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())
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.