← Back to libraryQuestion 283 of 468
🔬TestNG & JUnitIntermediate

Lifecycle Scope and the static @BeforeAll Requirement

📌 Definition:

In JUnit 5, class-level lifecycle methods (@BeforeAll/@AfterAll) must be STATIC by default because the test class is re-instantiated per test method; TestNG's @BeforeClass/@AfterClass are instance methods.

📖 Detailed Explanation:

JUnit 5 creates a NEW instance of the test class for EACH @Test method (PER_METHOD lifecycle) to ensure isolation, so @BeforeAll/@AfterAll — which run once for the whole class — must be static (they can't belong to a per-test instance). You can change this with @TestInstance(Lifecycle.PER_CLASS), which reuses one instance and then allows non-static @BeforeAll. TestNG instantiates the class once and runs @BeforeClass as an instance method by default. This difference explains a common JUnit 5 gotcha ('@BeforeAll must be static') and affects how you share state across a class's tests.

🔑 Key Points:
  • JUnit5 creates a new test-class instance PER test method (isolation)
  • So @BeforeAll/@AfterAll must be static by default
  • @TestInstance(PER_CLASS) reuses one instance → non-static allowed
  • TestNG @BeforeClass is an instance method (single instance)
🌍 Real-World Example:

A JUnit 5 test fails to compile because @BeforeAll void setup() isn't static; making it static (or adding @TestInstance(PER_CLASS)) fixes it — a difference from TestNG where @BeforeClass is just an instance method.

🎯 Scenario-Based Interview Question:

A developer moving from TestNG to JUnit 5 gets '@BeforeAll method must be static'. Why, and what are the two fixes?