Differenza tra @Before, @BeforeClass, @BeforeEach e @BeforeAll


432

Qual è la differenza principale tra

  • @Before e @BeforeClass
    • e in JUnit 5 @BeforeEache@BeforeAll
  • @After e @AfterClass

Secondo JUnit Api @Before viene utilizzato nel seguente caso:

Quando si scrivono i test, è comune scoprire che diversi test richiedono oggetti simili creati prima di poter essere eseguiti.

Considerando che @BeforeClasspuò essere utilizzato per stabilire una connessione al database. Ma non puoi @Beforefare lo stesso?

Risposte:


624

Il codice contrassegnato @Beforeviene eseguito prima di ogni test, mentre @BeforeClassviene eseguito una volta prima dell'intero dispositivo di test. Se la tua classe di test ha dieci test, il @Beforecodice verrà eseguito dieci volte, ma @BeforeClassverrà eseguito una sola volta.

In generale, si utilizza @BeforeClassquando più test devono condividere lo stesso codice di installazione computazionalmente costoso. Stabilire una connessione al database rientra in questa categoria. È possibile spostare il codice da @BeforeClassin @Before, ma l'esecuzione del test potrebbe richiedere più tempo. Si noti che il codice contrassegnato @BeforeClassviene eseguito come inizializzatore statico, quindi verrà eseguito prima della creazione dell'istanza di classe del dispositivo di prova.

In JUnit 5 , i tag @BeforeEache @BeforeAllsono gli equivalenti di @Beforee @BeforeClassin JUnit 4. I loro nomi sono un po 'più indicativi di quando vengono eseguiti, interpretati vagamente: "prima di ogni test" e "una volta prima di tutti i test".


4
Ah, ora ha senso l'esempio con la connessione DB. Grazie!
user1170330

6
@pacoverflow @BeforeClasè statico. Viene eseguito prima della creazione delle istanze della classe di test.
dasblinkenlight,

1
Tieni presente che quando usi @BeforeClass il tuo metodo / parametro deve essere statico
tiagocarvalho92

Non è direttamente correlato, ma questo è un modo per calcolare il contatore "Test per categoria" .
Bsquare ℬℬ

Aggiungerò solo che @BeforeAllpotrebbe non essere statico e chiamerò ogni nuova esecuzione dell'istanza di prova. Vedi la risposta corrispondente stackoverflow.com/a/55720750/1477873
Sergey

124

Le differenze tra ciascuna annotazione sono:

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

La maggior parte delle annotazioni in entrambe le versioni sono uguali, ma alcune differiscono.

Riferimento

Ordine di esecuzione.

Casella tratteggiata -> annotazione opzionale.

inserisci qui la descrizione dell'immagine


10

Prima e prima della classe in JUnit

L' @Beforeannotazione della funzione verrà eseguita prima di ciascuna delle funzioni di test nella classe con @Testannotazione, ma la funzione con @BeforeClassverrà eseguita solo una volta prima di tutte le funzioni di test nella classe.

Analogamente la funzione con @Afterannotazione verrà eseguita dopo ciascuna delle funzioni di test nella classe con @Testannotazione, ma la funzione con @AfterClassverrà eseguita solo una volta dopo tutte le funzioni di test nella classe.

SampleClass

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

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

Test di esempio

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

}

Produzione

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

Nel giugno 5

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

1
Ottimo esempio.
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())
    }
}

Uguale a

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())
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.