0
0
JUnittesting~15 mins

Nested class lifecycle in JUnit - Build an Automation Script

Choose your learning style9 modes available
Verify JUnit nested test class lifecycle methods execution order
Preconditions (2)
Step 1: Create a top-level test class with @BeforeAll and @AfterAll static methods
Step 2: Inside it, create a nested test class annotated with @Nested
Step 3: Add @BeforeEach and @AfterEach methods in both top-level and nested classes
Step 4: Add a simple test method in the nested class that asserts true is true
Step 5: Run the test suite
✅ Expected Result: The lifecycle methods execute in the correct order: top-level @BeforeAll runs once before all tests, nested @BeforeEach runs before each nested test, nested test runs, nested @AfterEach runs after each nested test, and top-level @AfterAll runs once after all tests. The test passes.
Automation Requirements - JUnit 5
Assertions Needed:
Verify that the nested test method runs and passes
Verify lifecycle methods execute in expected order by capturing output or state
Best Practices:
Use @Nested annotation for inner test classes
Use @BeforeAll and @AfterAll as static methods in top-level class
Use @BeforeEach and @AfterEach for setup and teardown in both classes
Use assertions from org.junit.jupiter.api.Assertions
Keep test methods simple and focused
Automated Solution
JUnit
import org.junit.jupiter.api.*;
import java.util.ArrayList;
import java.util.List;

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

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

    @BeforeAll
    static void beforeAllTop() {
        System.out.println("Top-level BeforeAll");
    }

    @AfterAll
    static void afterAllTop() {
        System.out.println("Top-level AfterAll");
    }

    @BeforeEach
    void beforeEachTop() {
        lifecycleOrder.add("Top BeforeEach");
    }

    @AfterEach
    void afterEachTop() {
        lifecycleOrder.add("Top AfterEach");
    }

    @Nested
    class InnerNested {

        @BeforeEach
        void beforeEachNested() {
            lifecycleOrder.add("Nested BeforeEach");
        }

        @AfterEach
        void afterEachNested() {
            lifecycleOrder.add("Nested AfterEach");
        }

        @Test
        void nestedTest() {
            lifecycleOrder.add("Nested Test");
            Assertions.assertTrue(true);
        }
    }

    @Test
    void verifyLifecycleOrder() {
        // Run nested test manually to capture lifecycle order
        InnerNested nested = new InnerNested();
        nested.beforeEachNested();
        nested.nestedTest();
        nested.afterEachNested();

        // Top-level beforeEach and afterEach should be called around nested test
        // Simulate top-level lifecycle calls
        beforeEachTop();
        afterEachTop();

        // Check that lifecycleOrder contains expected sequence
        List<String> expectedOrder = List.of(
            "Top BeforeEach",
            "Nested BeforeEach",
            "Nested Test",
            "Nested AfterEach",
            "Top AfterEach"
        );

        Assertions.assertEquals(expectedOrder, lifecycleOrder);
    }
}

This test class demonstrates the lifecycle of JUnit 5 nested classes.

The NestedLifecycleTest class has lifecycle methods annotated with @BeforeAll, @AfterAll, @BeforeEach, and @AfterEach. The nested class InnerNested also has @BeforeEach and @AfterEach methods and a test method.

We use a List<String> to record the order of lifecycle method calls and the test execution.

The verifyLifecycleOrder test method manually calls the nested lifecycle methods and test to simulate the order and then asserts the recorded order matches the expected sequence.

This approach helps verify the nested class lifecycle behavior clearly and ensures the test passes if the lifecycle methods run in the correct order.

Common Mistakes - 3 Pitfalls
Using non-static methods for @BeforeAll and @AfterAll in top-level class
Not annotating inner class with @Nested
Assuming @BeforeAll and @AfterAll run for each nested test
Bonus Challenge

Now add data-driven testing to the nested test method with 3 different input strings verifying they are not empty

Show Hint