feat(testing): boot lazily instead of eagerly in beforeEach

beforeEach called ensureStarted(), so every FlashTest field in a class booted
for every test whether or not that test touched it — a class holding four
servers paid for four boots per test. Booting is already lazy on first access,
so the hook was only ever forcing work forward.

Neither hook starts anything now. beforeAll still records that a static field
owns the class-scoped lifecycle, which is what keeps afterEach from tearing a
class-scoped server down after the first test.

This also lets an application read @TempDir inside configure(): JUnit populates
those during instance post-processing, before the first test body but after
extension beforeEach callbacks would have fired.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Zakaria El Orche
2026-09-09 11:05:06 +00:00
co-authored by Claude Opus 5
parent fa5a025c93
commit 1c207cf94c
@@ -165,10 +165,14 @@ public final class FlashTest implements BeforeAllCallback, AfterAllCallback,
// ── JUnit lifecycle ──────────────────────────────────────────────────────
// A static field receives class- AND method-level callbacks, so afterEach would otherwise
// tear the server down after the first test. classScoped records which tier owns it.
//
// Neither hook starts anything: booting stays lazy, so a class holding several servers
// only pays for the ones a test actually touches, and an application whose configure()
// reads @TempDir sees it populated rather than null.
@Override public void beforeAll(ExtensionContext context) { classScoped = true; ensureStarted(); }
@Override public void beforeAll(ExtensionContext context) { classScoped = true; }
@Override public void afterAll(ExtensionContext context) { stop(); }
@Override public void beforeEach(ExtensionContext context) { if (!classScoped) ensureStarted(); }
@Override public void beforeEach(ExtensionContext context) { /* lazy */ }
@Override public void afterEach(ExtensionContext context) { if (!classScoped) stop(); }
// ── Internals ────────────────────────────────────────────────────────────