0
0
JUnittesting~15 mins

Execution order of lifecycle methods in JUnit - Build an Automation Script

Choose your learning style9 modes available
Verify the execution order of JUnit lifecycle methods
Preconditions (2)
Step 1: Create a test class with methods annotated with @BeforeAll, @BeforeEach, @Test, @AfterEach, and @AfterAll
Step 2: Add print statements in each lifecycle method to log their execution
Step 3: Run the test class
Step 4: Observe the console output for the order of method execution
✅ Expected Result: The console output shows the lifecycle methods executing in this order: @BeforeAll once, @BeforeEach before each test, @Test methods, @AfterEach after each test, and @AfterAll once at the end
Automation Requirements - JUnit 5
Assertions Needed:
Verify that @BeforeAll method runs once before all tests
Verify that @BeforeEach method runs before each test method
Verify that @AfterEach method runs after each test method
Verify that @AfterAll method runs once after all tests
Best Practices:
Use @TestInstance(Lifecycle.PER_CLASS) to allow non-static @BeforeAll and @AfterAll methods
Use assertions to confirm the order of execution
Avoid using Thread.sleep; rely on proper test lifecycle hooks
Keep test methods independent and isolated
Automated Solution
JUnit
import org.junit.jupiter.api.*;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class LifecycleOrderTest {

    private final List<String> executionOrder = new ArrayList<>();

    @BeforeAll
    void beforeAll() {
        executionOrder.add("BeforeAll");
    }

    @BeforeEach
    void beforeEach() {
        executionOrder.add("BeforeEach");
    }

    @Test
    void testOne() {
        executionOrder.add("TestOne");
    }

    @Test
    void testTwo() {
        executionOrder.add("TestTwo");
    }

    @AfterEach
    void afterEach() {
        executionOrder.add("AfterEach");
    }

    @AfterAll
    void afterAll() {
        executionOrder.add("AfterAll");

        // Now verify the order
        // Expected order:
        // BeforeAll
        // BeforeEach, TestOne, AfterEach
        // BeforeEach, TestTwo, AfterEach
        // AfterAll

        List<String> expectedOrder = List.of(
            "BeforeAll",
            "BeforeEach", "TestOne", "AfterEach",
            "BeforeEach", "TestTwo", "AfterEach",
            "AfterAll"
        );

        assertEquals(expectedOrder, executionOrder, "Lifecycle methods did not execute in expected order");
    }
}

This test class uses JUnit 5 lifecycle annotations to track the order of method execution.

We use a list executionOrder to record each lifecycle method call.

@BeforeAll runs once before all tests, so it adds "BeforeAll" first.

@BeforeEach runs before each test method, so it adds "BeforeEach" before each test.

Each @Test method adds its own name to the list.

@AfterEach runs after each test method, adding "AfterEach".

@AfterAll runs once after all tests, adding "AfterAll" and then asserting the entire order matches the expected sequence.

We use @TestInstance(Lifecycle.PER_CLASS) to allow non-static @BeforeAll and @AfterAll methods for simplicity.

This approach confirms the lifecycle methods execute in the correct order by checking the list contents at the end.

Common Mistakes - 4 Pitfalls
{'mistake': 'Making @BeforeAll and @AfterAll methods non-static without using @TestInstance(PER_CLASS)', 'why_bad': "JUnit 5 requires @BeforeAll and @AfterAll to be static unless the test instance lifecycle is PER_CLASS, otherwise tests won't run correctly.", 'correct_approach': 'Use @TestInstance(TestInstance.Lifecycle.PER_CLASS) to allow non-static lifecycle methods or make them static.'}
Not verifying the execution order with assertions
Using print statements only without automated checks
Modifying shared state without isolation between tests
Bonus Challenge

Now add data-driven testing with 3 different test methods to verify lifecycle order for each

Show Hint