skip to content

Walk through the exact order in which JUnit 5 invokes constructor, @BeforeAll, @BeforeEach, @Test, @AfterEach, and @AfterAll for a two-test class — and how that sequence differs between PER_METHOD and PER_CLASS.

level: middleimportance: should knowfreq 42%

answer

  1. All → (ctor → Each → test → Each)* → All
  2. Constructor: once-per-test (PER_METHOD) vs once (PER_CLASS)
  3. Before = top-down, After = bottom-up with inheritance
  4. @BeforeEach/@AfterEach bracket every test in both modes
  5. Field initializers run with the constructor

basics

~20 s

@BeforeAll runs once at the start, @AfterAll once at the end. Around every @Test, JUnit runs the constructor then @BeforeEach before, and @AfterEach after. In PER_METHOD the constructor runs once per test; in PER_CLASS it runs only once.

solid answer

~50 s

For each test method JUnit's per-test cycle is: construct the instance, run @BeforeEach, run the @Test, run @AfterEach. Wrapping the whole class, @BeforeAll runs once before any test and @AfterAll once after all tests. The difference between lifecycles is how often the constructor fires: under PER_METHOD a new instance is built before every test, so the constructor runs once per @Test, and @BeforeAll/@AfterAll must be static. Under PER_CLASS the single instance is constructed exactly once for the class, so the constructor runs once total, and @BeforeAll/@AfterAll may be non-static. @BeforeEach/@AfterEach still bracket every individual test in both modes. With inheritance, superclass @BeforeAll/@BeforeEach run before subclass ones, and @AfterEach/@AfterAll run in reverse (subclass first). Extensions and @BeforeAll order can be further controlled, but the core bracket — All → (ctor → Each → test → Each)* → All — is the thing to know.

code

java · 14 lines
java
class LifecycleLog {
    LifecycleLog() { System.out.println("ctor"); }
    @BeforeAll static void beforeAll() { System.out.println("beforeAll"); }
    @BeforeEach void beforeEach() { System.out.println("beforeEach"); }
    @AfterEach  void afterEach()  { System.out.println("afterEach"); }
    @AfterAll  static void afterAll() { System.out.println("afterAll"); }
    @Test void t1() { System.out.println("t1"); }
    @Test void t2() { System.out.println("t2"); }
}
// PER_METHOD output:
// beforeAll
// ctor, beforeEach, t1, afterEach
// ctor, beforeEach, t2, afterEach
// afterAll

go deeper

for a junior

Recites the basic bracket: @BeforeAll once, @BeforeEach/@AfterEach around each test, @AfterAll once.

for a middle

Correctly maps how often the constructor fires per lifecycle and where field initializers fit; knows @BeforeEach brackets every test in both modes.

for a senior

Adds inheritance ordering (top-down before, bottom-up after) and the field-reset implications of once-vs-per-test construction.

for a principal

Uses the lifecycle model to design layered test base classes and extension ordering without creating hidden hook dependencies.

## The fixed bracket JUnit 5's lifecycle callbacks always nest like this around a class run: ``` @BeforeAll // once, before everything ┌ per test (repeat for each @Test) ┐ │ <constructor> │ │ @BeforeEach │ │ @Test │ │ @AfterEach │ └───────────────────────────────────┘ @AfterAll // once, after everything ``` The **constructor** is part of the *per-test* region conceptually because JUnit must have an instance to run `@BeforeEach`/`@Test` on. How often it actually runs depends on the lifecycle. ## PER_METHOD (default) — two tests ``` @BeforeAll (static) new TestClass() // for test1 @BeforeEach test1 @AfterEach new TestClass() // for test2 ← constructor runs AGAIN @BeforeEach test2 @AfterEach @AfterAll (static) ``` The constructor runs **once per test** (here, twice). Because there's no single shared instance, `@BeforeAll`/`@AfterAll` **must be static**. ## PER_CLASS — two tests ``` new TestClass() // ONCE for the whole class @BeforeAll (non-static OK) @BeforeEach test1 @AfterEach @BeforeEach test2 @AfterEach @AfterAll (non-static OK) ``` The constructor runs **exactly once**. `@BeforeAll`/`@AfterAll` may be **non-static** (they run on the shared instance). Note: under PER_CLASS the instance must exist before `@BeforeAll` can run on it, so construction precedes `@BeforeAll`. `@BeforeEach`/`@AfterEach` still bracket **each** test in both modes. ## Common gotcha: field initializers and the constructor Instance-field initializers and the constructor run together as 'construction.' In PER_METHOD that means fields are re-initialized per test (fresh state). In PER_CLASS they run only once, so field initializers do **not** reset between tests — another reason mutable shared state needs a `@BeforeEach` reset. ## Inheritance ordering With a superclass: - **Before** hooks run **top-down**: superclass `@BeforeAll` then subclass `@BeforeAll`; superclass `@BeforeEach` then subclass `@BeforeEach`. - **After** hooks run **bottom-up**: subclass `@AfterEach` then superclass `@AfterEach`; subclass `@AfterAll` then superclass `@AfterAll`. This mirrors construction/destruction symmetry — set up from the base up, tear down from the leaf down. ## Multiple hooks of the same kind If a class has several `@BeforeEach` methods, their relative order is **not guaranteed** by default (you can influence it with `@Order` via `MethodOrderer` only for `@Test`s; for lifecycle methods JUnit applies a deterministic-but-unspecified order). Don't write hooks that depend on each other's order. ## Why this matters Knowing the bracket lets you place setup correctly: expensive once-only work → `@BeforeAll`; per-test fresh state → `@BeforeEach`; resource release → `@AfterEach`/`@AfterAll`. And knowing the constructor runs once (PER_CLASS) vs per-test (PER_METHOD) explains why field state does or doesn't reset.

  • In PER_METHOD with three @Test methods, how many times does the constructor run?
    Three times — once before each test, because a new instance is created per @Test.
  • With inheritance, does the subclass or superclass @AfterEach run first?
    The subclass @AfterEach runs first; teardown hooks run bottom-up (leaf to base), the reverse of the top-down setup order.

saying these in an interview costs you the question

  • Putting @AfterAll before @AfterEach in the sequence
  • Saying the constructor runs once in PER_METHOD (it runs once per test)
  • Claiming @BeforeEach runs only once per class
  • Reversing inheritance order (superclass teardown before subclass)

context