461

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
  • 10,050
  • 6
  • 44
  • 85
Evgenij Reznik
  • 16,046
  • 33
  • 87
  • 157

6 Answers6

670

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
  • 3,314
  • 27
  • 45
Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
  • 7
    @pacoverflow `@BeforeClas` is static. It runs before test class instances are created. – Sergey Kalinichenko Oct 05 '15 at 15:00
  • 1
    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
136

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
  • 7,870
  • 2
  • 42
  • 43
11

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
  • 926
  • 10
  • 12
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())
    }
}
kreker
  • 5,453
  • 4
  • 36
  • 32
2

@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
  • 13,571
  • 5
  • 105
  • 98
0

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,071
  • 1
  • 9
  • 20