510

What is the main difference between

  • @Before and @BeforeClass
    • and in JUnit 5 @BeforeEach and @BeforeAll
  • @After and @AfterClass

According to the JUnit Api @Before is used in the following case:

When writing tests, it is common to find that several tests need similar objects created before they can run.

Whereas @BeforeClass can be used to establish a database connection. But couldn't @Before do the same?

Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
Evgenij Reznik
  • 17,916
  • 39
  • 104
  • 181

7 Answers7

741

The code marked @Before is executed before each test, while @BeforeClass runs once before the entire test fixture. If your test class has ten tests, @Before code will be executed ten times, but @BeforeClass will be executed only once.

In general, you use @BeforeClass when multiple tests need to share the same computationally expensive setup code. Establishing a database connection falls into this category. You can move code from @BeforeClass into @Before, but your test run may take longer. Note that the code marked @BeforeClass is run as static initializer, therefore it will run before the class instance of your test fixture is created.

In JUnit 5, the tags @BeforeEach and @BeforeAll are the equivalents of @Before and @BeforeClass in JUnit 4. Their names are a bit more indicative of when they run, loosely interpreted: 'before each tests' and 'once before all tests'.

Erik
  • 4,305
  • 3
  • 36
  • 54
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 9
    @pacoverflow `@BeforeClas` is static. It runs before test class instances are created. – Sergey Kalinichenko Oct 05 '15 at 15:00
  • 2
    Keep in mind that when you use @BeforeClass your method/parameter needs to be static – tiagocarvalho92 May 12 '17 at 13:19
  • It is not directly related, but this is a way to [compute 'Tests by Category' counter](https://stackoverflow.com/a/53778167/10524205). – Bsquare ℬℬ Jan 18 '19 at 12:43
  • I will only add that `@BeforeAll` may be non-static and call on every new test-instance run. See the corresponding answer https://stackoverflow.com/a/55720750/1477873 – Sergey Apr 30 '19 at 09:22
  • are you sure `Before` and `BeforeEach` are the same things because my test cases fail the mocks when i use `@Before` on my `init()` function but works with `@BeforeEach` – fireball.1 Oct 25 '20 at 14:42
  • @fireball.1Same thing is happening with me. – shiva Jan 11 '21 at 05:56
  • @shiva This means that you are running JUnit4, because `@Before` and `@BeforeEach` do not coexist. [See the migration guide for the information](https://junit.org/junit5/docs/current/user-guide/#migrating-from-junit4-tips). – Sergey Kalinichenko Jan 11 '21 at 11:32
171

Difference between each annotation are :

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

Most of annotations in both versions are same, but few differs.

Reference

Order of Execution.

Dashed box -> optional annotation.

enter image description here

Joby Wilson Mathews
  • 10,528
  • 6
  • 54
  • 53
18

Before and BeforeClass in JUnit

The function @Before annotation will be executed before each of test function in the class having @Test annotation but the function with @BeforeClass will be execute only one time before all the test functions in the class.

Similarly function with @After annotation will be executed after each of test function in the class having @Test annotation but the function with @AfterClass will be execute only one time after all the test functions in the class.

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

}

Output

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

In Junit 5

@Before = @BeforeEach
@BeforeClass = @BeforeAll
@After = @AfterEach
@AfterClass = @AfterAll
Dhyan Mohandas
  • 1,126
  • 11
  • 12
10

JUnit @BeforeEach, @AfterEach, @BeforeAll, @AfterAll

@Before(JUnit4) -> @BeforeEach(JUnit5) - method is called before every test

@After(JUnit4) -> @AfterEach(JUnit5) - method is called after every test

@BeforeClass(JUnit4) -> @BeforeAll(JUnit5) - static method is called before executing all tests in this class. It can be a large task as starting server, read file, making db connection...

@AfterClass(JUnit4) -> @AfterAll(JUnit5) - static method is called after executing all tests in this class.

yoAlex5
  • 29,217
  • 8
  • 193
  • 205
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())
    }
}

Same as

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())
    }
}
k4dima
  • 6,070
  • 5
  • 41
  • 39
1

The basic difference between all these annotations is as follows -

  1. @BeforeEach - Use to run a common code before( eg setUp) each test method execution. analogous to JUnit 4’s @Before.
  2. @AfterEach - Use to run a common code after( eg tearDown) each test method execution. analogous to JUnit 4’s @After.
  3. @BeforeAll - Use to run once per class before any test execution. analogous to JUnit 4’s @BeforeClass.
  4. @AfterAll - Use to run once per class after all test are executed. analogous to JUnit 4’s @AfterClass.

All these annotations along with the usage is defined on Codingeek - Junit5 Test Lifecycle

Hitesh Garg
  • 1,211
  • 1
  • 10
  • 21
0

@BeforeClass will be run before the entire test suits whereas @Before will be run is executed before each test, while @BeforeClass runs once before the entire test fixture. If your test class has ten tests, @Before code will be executed ten times, but @BeforeClass will be executed only once.

Abdur Rahman
  • 1,420
  • 1
  • 21
  • 32