JUnit 5's extension model defines BeforeAllCallback, BeforeEachCallback, BeforeTestExecutionCallback and their After* counterparts. In what order do these run around a single test method, and how does that order change when several extensions are registered?
answer
- BeforeAll→@BeforeAll→BeforeEach→@BeforeEach→BeforeTestExecution→test
- After* mirrors, TestExecution pair innermost
- extension callbacks wrap the user's annotated methods
- multiple extensions: before in order, after in reverse (onion)
- After* still runs after a failure; exceptions aggregated
basics
~10 sOrder is BeforeAllCallback, @BeforeAll, BeforeEachCallback, @BeforeEach, BeforeTestExecutionCallback, the test, AfterTestExecutionCallback, @AfterEach, AfterEachCallback, @AfterAll, AfterAllCallback. Multiple extensions nest like an onion: Before* in registration order, After* in reverse.
solid answer
~50 sFor one test method the documented sequence is: 1. `BeforeAllCallback` 2. `@BeforeAll` methods 3. `BeforeEachCallback` 4. `@BeforeEach` methods 5. `BeforeTestExecutionCallback` 6. the `@Test` method 7. `TestExecutionExceptionHandler` (only if it threw) 8. `AfterTestExecutionCallback` 9. `@AfterEach` methods 10. `AfterEachCallback` 11. `@AfterAll` methods 12. `AfterAllCallback` So extension callbacks **wrap** the user's annotated lifecycle methods on the outside, except the `*TestExecution*` pair, which sits **inside** `@BeforeEach`/`@AfterEach` and hugs the test invocation itself — that is why timing and per-invocation instrumentation belong there. With several extensions, JUnit applies onion semantics: `Before*` callbacks run in registration order, `After*` callbacks in reverse, so each extension tears down inside the one registered before it. Registration order for declarative extensions follows the `@ExtendWith` declarations; `@Order` on `@RegisterExtension` fields controls it explicitly. `After*` callbacks still run when earlier steps fail, and failures are aggregated rather than short-circuiting the rest of the teardown.
code
java · 18 linesclass TimingExtension implements BeforeEachCallback, BeforeTestExecutionCallback,
AfterTestExecutionCallback, AfterEachCallback {
private long start;
@Override public void beforeEach(ExtensionContext ctx) {
// runs BEFORE the user's @BeforeEach — prepare what their setup needs
}
@Override public void beforeTestExecution(ExtensionContext ctx) {
start = System.nanoTime(); // brackets the test body only
}
@Override public void afterTestExecution(ExtensionContext ctx) {
long ms = (System.nanoTime() - start) / 1_000_000;
ctx.publishReportEntry("durationMs", String.valueOf(ms));
}
@Override public void afterEach(ExtensionContext ctx) {
// runs AFTER the user's @AfterEach — safe place to release resources
}
}go deeper
Recite the sequence and the key fact that extension callbacks sit outside the user's @BeforeEach/@AfterEach, with the TestExecution pair innermost.
Explain why you would pick each ring — user setup dependencies, timing the body only, cleanup that must outlive teardown — and the reverse ordering of After* callbacks.
Add composition: registration order sources, @Order on @RegisterExtension, nesting and inheritance, and the guarantee that teardown still runs and exceptions aggregate.
Discuss it as a composition contract: designing extensions that nest safely with third-party ones, avoiding hidden ordering dependencies, and choosing container-scoped versus test-scoped rings for expensive resources.
## Why the order matters An extension is a class implementing one or more callback interfaces from `org.junit.jupiter.api.extension`. Once registered, JUnit invokes it at fixed points around test execution. Getting the order right is the difference between an extension that reliably sets up a database transaction, a mock server or a clock, and one that races the user's own `@BeforeEach`. ## The canonical sequence For a single test method in a class, JUnit Jupiter documents this relative order: 1. **`BeforeAllCallback`** — once per container, before any user class-level setup. 2. **`@BeforeAll`** — the user's static setup methods. 3. *(test instance creation and `TestInstancePostProcessor` for the default per-method lifecycle)* 4. **`BeforeEachCallback`** — extension setup per test. 5. **`@BeforeEach`** — the user's per-test setup. 6. **`BeforeTestExecutionCallback`** — immediately before the test method runs. 7. **the `@Test` method body** 8. **`TestExecutionExceptionHandler`** — only if the body threw. 9. **`AfterTestExecutionCallback`** — immediately after the body. 10. **`@AfterEach`** 11. **`AfterEachCallback`** 12. **`@AfterAll`** 13. **`AfterAllCallback`** Read it as concentric rings. The outermost ring is `BeforeAllCallback`/`AfterAllCallback`; inside it the user's `@BeforeAll`/`@AfterAll`; inside that `BeforeEachCallback`/`AfterEachCallback`; then `@BeforeEach`/`@AfterEach`; and innermost, hugging the invocation, `BeforeTestExecutionCallback`/`AfterTestExecutionCallback`. ## Which ring to pick The practical consequences: - **`BeforeEachCallback` runs before the user's `@BeforeEach`.** So if a test's own setup needs something your extension provides — an open transaction, a started container, a fixed clock — that must be done in `BeforeEachCallback`, not in `BeforeTestExecutionCallback`, which is too late. - **`AfterEachCallback` runs after the user's `@AfterEach`.** Cleanup that must outlive the user's teardown (closing a transaction the user's code still needed, stopping a server) belongs there. - **The `*TestExecution*` pair brackets only the test body.** It excludes user setup and teardown, which makes it the correct home for measuring the duration of the test itself, capturing a screenshot at the exact moment of failure, or asserting on state produced strictly by the body. `AfterTestExecutionCallback` can also inspect the outcome via the extension context's execution exception. ## Multiple extensions: onion, not queue When several extensions implement the same callback, JUnit wraps rather than chains: **`Before*` callbacks are invoked in registration order and `After*` callbacks in reverse registration order.** Extension A registered first therefore sets up first and tears down last, guaranteeing that B's teardown still sees A's setup — the same discipline as nested try/finally blocks or constructor/destructor ordering. Registration order comes from where the extension was declared: declarative `@ExtendWith` declarations are applied in the order they appear (class-level before method-level; superclass and enclosing-class registrations before the current class's). Programmatic extensions registered on `@RegisterExtension` fields are ordered deterministically and can be sequenced explicitly with `@Order`. Extensions registered automatically through the `ServiceLoader` mechanism come first of all when that feature is enabled. Any extension type is registered at most once per context, so declaring the same one twice does not double the callbacks. ## Inheritance and nesting User lifecycle methods follow their own inherited order: superclass `@BeforeEach` before subclass `@BeforeEach`, subclass `@AfterEach` before superclass `@AfterEach`. For `@Nested` classes, the outer class's `@BeforeEach` and the outer registrations run before the inner ones, again unwinding in reverse — extensions registered on an outer class apply to nested classes too. ## Failure behaviour This is what makes the model usable for resource management: **`After*` callbacks still run when something earlier failed.** If `@BeforeEach` throws, the test is not executed, but the `After*` chain unwinds so resources are released. Exceptions thrown by multiple callbacks are aggregated and reported together (as suppressed exceptions on the primary failure) rather than one silently swallowing another. That means your teardown must be defensive — it can be invoked in a state where its corresponding setup partly failed, so null-check and guard accordingly. ## A short mental checklist when writing an extension - Does the user's `@BeforeEach` need my state? → `BeforeEachCallback`. - Do I need to bracket only the test body (timing, screenshots, state diff)? → `BeforeTestExecutionCallback`/`AfterTestExecutionCallback`. - Must my cleanup outlive the user's teardown? → `AfterEachCallback`. - Is the resource expensive and shareable across the whole class? → `BeforeAllCallback`/`AfterAllCallback`. - Am I composing with another extension that must wrap mine? → control registration order (`@Order` on `@RegisterExtension`, or declaration sequence).
- You need an extension to open a database transaction that the test's own @BeforeEach fixture inserts into. Which callback do you implement, and why not BeforeTestExecutionCallback?Implement BeforeEachCallback, because it runs before the user's @BeforeEach, so their fixture inserts inside your transaction. BeforeTestExecutionCallback fires after all user setup and immediately before the test body, by which point the fixture would already have been written outside the transaction. Roll back in AfterEachCallback, which runs after the user's @AfterEach.
- Two extensions are registered on the same class, A then B. If B's afterEach throws, does A's afterEach still run?Yes. After* callbacks unwind in reverse registration order and JUnit continues the chain even when one throws, aggregating the failures so none is silently lost. That is what makes the model safe for resource cleanup — you should still write defensive teardown, since your setup may have failed partway.
Concentric rings, or nested try/finally: the first extension in is the last one out, and the TestExecution pair is the innermost ring, touching the test body itself.
saying these in an interview costs you the question
- Believing extension BeforeEachCallback runs after the user's @BeforeEach
- Thinking BeforeTestExecutionCallback and BeforeEachCallback are interchangeable
- Assuming After* callbacks are skipped when setup or the test failed
- Expecting multiple extensions to tear down in registration order rather than reverse