Verify that JUnit test instance lifecycle is per class
Preconditions (2)
✅ Expected Result: The counter value should be 1 after the first test and 2 after the second test, showing the same test instance is used for both tests
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import static org.junit.jupiter.api.Assertions.assertEquals; @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class TestInstancePerClassLifecycleTest { private int counter = 0; @Test void testIncrementCounterFirst() { counter++; assertEquals(1, counter, "Counter should be 1 after first test"); } @Test void testIncrementCounterSecond() { counter++; assertEquals(2, counter, "Counter should be 2 after second test"); } }
The test class is annotated with @TestInstance(Lifecycle.PER_CLASS) to tell JUnit to use the same instance for all test methods.
The counter is an instance variable initialized to 0.
Each test method increments the counter by 1 and asserts the expected value.
Because the same instance is used, the counter value accumulates across tests, verifying the lifecycle behavior.
Now add a third test method that resets the counter to 0 and verify it resets correctly
@TestInstance(TestInstance.Lifecycle.PER_CLASS) annotation do in a JUnit test class?@TestInstance(TestInstance.Lifecycle.PER_CLASS) annotation tells JUnit to create only one instance of the test class for all test methods.@TestInstance(TestInstance.Lifecycle.PER_CLASS).TestInstance. prefix, @TestInstance(PER_CLASS) is incomplete, and @TestInstance(Lifecycle.PER_METHOD) uses PER_METHOD which is default, not PER_CLASS.@TestInstance(TestInstance.Lifecycle.PER_CLASS):
import org.junit.jupiter.api.*;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CounterTest {
private int count = 0;
@Test
void testIncrement() {
count++;
Assertions.assertEquals(1, count);
}
@Test
void testIncrementAgain() {
count++;
Assertions.assertEquals(2, count);
}
}
What will be the result when running these tests?count keeps its value between tests.@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class SampleTest {
private List<String> list = new ArrayList<>();
@BeforeEach
void setup() {
list.clear();
list.add("start");
}
@Test
void testOne() {
list.add("one");
Assertions.assertEquals(2, list.size());
}
@Test
void testTwo() {
list.add("two");
Assertions.assertEquals(2, list.size());
}
}
If the list.clear() call is removed from setup(), what problem will occur?list.clear(), the list keeps accumulating elements from previous tests because the same instance is reused.@TestInstance(TestInstance.Lifecycle.PER_CLASS). Which of the following is the best practice to avoid flaky tests?@BeforeEach ensures each test starts fresh, preventing flaky or dependent tests.@BeforeEach method. -> Option CPass the test and this pattern moves unknown