Nested class lifecycle helps organize tests in groups and control how often setup and cleanup happen for each group.
0
0
Nested class lifecycle in JUnit
Introduction
You want to group related tests inside a main test class.
You need separate setup for different groups of tests.
You want to run setup once per group instead of before every test.
You want clearer test reports showing test groups.
You want to avoid repeating setup code for similar tests.
Syntax
JUnit
import org.junit.jupiter.api.*; @TestInstance(TestInstance.Lifecycle.PER_CLASS) class OuterTest { @BeforeAll void beforeAllOuter() { // runs once before all tests in OuterTest } @Nested @TestInstance(TestInstance.Lifecycle.PER_CLASS) class InnerTest { @BeforeAll void beforeAllInner() { // runs once before all tests in InnerTest } @Test void testSomething() { // test code } } }
Use @Nested to create a nested test class inside an outer test class.
Lifecycle annotations like @BeforeAll run once per class instance.
Examples
This example shows a nested class with setup before each test inside it.
JUnit
import org.junit.jupiter.api.*; class OuterTest { @BeforeAll static void setupAll() { System.out.println("Setup once for all tests"); } @Nested class GroupOne { @BeforeEach void setupEach() { System.out.println("Setup before each test in GroupOne"); } @Test void testA() { System.out.println("Running testA"); } } }
Using
@TestInstance(PER_CLASS) allows @BeforeAll to be non-static in nested classes.JUnit
import org.junit.jupiter.api.*; @TestInstance(TestInstance.Lifecycle.PER_CLASS) class OuterTest { @Nested @TestInstance(TestInstance.Lifecycle.PER_CLASS) class InnerTest { @BeforeAll void init() { System.out.println("Init once for InnerTest"); } @Test void testOne() { System.out.println("Test one running"); } } }
Sample Program
This test class has two nested groups: AdditionTests and SubtractionTests. Setup methods run at different times for each group. Assertions check correct math results.
JUnit
import org.junit.jupiter.api.*; @TestInstance(TestInstance.Lifecycle.PER_CLASS) class CalculatorTest { @BeforeAll void setupAll() { System.out.println("Setup for all tests"); } @Nested @TestInstance(TestInstance.Lifecycle.PER_CLASS) class AdditionTests { @BeforeAll void setupAddition() { System.out.println("Setup for addition tests"); } @Test void testAddPositive() { int result = 2 + 3; Assertions.assertEquals(5, result); System.out.println("testAddPositive passed"); } @Test void testAddNegative() { int result = -1 + -1; Assertions.assertEquals(-2, result); System.out.println("testAddNegative passed"); } } @Nested class SubtractionTests { @BeforeEach void setupSubtraction() { System.out.println("Setup before each subtraction test"); } @Test void testSubtract() { int result = 5 - 3; Assertions.assertEquals(2, result); System.out.println("testSubtract passed"); } } }
OutputSuccess
Important Notes
Nested classes help keep tests organized and readable.
Use @TestInstance(TestInstance.Lifecycle.PER_CLASS) to allow non-static @BeforeAll in nested classes.
Setup in outer class runs before nested class setups.
Summary
Nested classes group related tests inside a main test class.
Lifecycle annotations control setup and cleanup timing per class or test.
Using nested lifecycle improves test organization and efficiency.