Context
`DbUnitExtension.resolveConfiguration()` calls `AnnotatedTestConfiguration.from(...)`, which reflectively instantiates the configured `dataFileLoader`, `failureHandler`, and `propertiesProvider`, and scans/sorts a `VerifyTableDefinitionCatalog`'s fields - for every test method, even when all of that comes from one unchanging class-level `@DbUnitConfig`. `resolveExecutor()`'s existing cache (an `ExtensionContext.Store` entry keyed under `EXECUTOR_KEY`) is scoped to the per-test-method `ExtensionContext`, so nothing carries over between methods in the same test class - the class-level reflection cost is paid again on every single `@Test`.
Why this needs a design decision, not a quick fix
`AnnotatedTestConfiguration.from()` currently combines class-level (`@DbUnitConfig`) and method-level (`@DbUnitPrep`, `@DbUnitExpected`, `@DbUnitSetup`, `@DbUnitTearDown`, `@DbUnitRowCountCheck`) annotation data into one immutable object in a single pass. Splitting the "class-level, safely cacheable" pieces from the "method-level, must-recompute-per-test" pieces means restructuring the class this entire feature's correctness rests on: method-level annotations correctly overriding class-level `@DbUnitConfig` attributes is the single most safety-critical piece of behavior in the whole annotation system (see the design note in the type-level Javadoc of `DbUnitExpected` on how these resolve). A caching change done carelessly risks a stale-class-level-state bug that would be far worse than the performance cost it's meant to fix.
Impact
Reflection overhead, not a correctness issue - likely on the order of microseconds to low milliseconds per test method; only meaningfully adds up for very large test classes.
Found via
Discovered during a /code-review high pass on feat/annotation-driven-setup ahead of merging #753, then deliberately deferred rather than forced into a risky restructuring on that branch.
Context
`DbUnitExtension.resolveConfiguration()` calls `AnnotatedTestConfiguration.from(...)`, which reflectively instantiates the configured `dataFileLoader`, `failureHandler`, and `propertiesProvider`, and scans/sorts a `VerifyTableDefinitionCatalog`'s fields - for every test method, even when all of that comes from one unchanging class-level `@DbUnitConfig`. `resolveExecutor()`'s existing cache (an `ExtensionContext.Store` entry keyed under `EXECUTOR_KEY`) is scoped to the per-test-method `ExtensionContext`, so nothing carries over between methods in the same test class - the class-level reflection cost is paid again on every single `@Test`.
Why this needs a design decision, not a quick fix
`AnnotatedTestConfiguration.from()` currently combines class-level (`@DbUnitConfig`) and method-level (`@DbUnitPrep`, `@DbUnitExpected`, `@DbUnitSetup`, `@DbUnitTearDown`, `@DbUnitRowCountCheck`) annotation data into one immutable object in a single pass. Splitting the "class-level, safely cacheable" pieces from the "method-level, must-recompute-per-test" pieces means restructuring the class this entire feature's correctness rests on: method-level annotations correctly overriding class-level `@DbUnitConfig` attributes is the single most safety-critical piece of behavior in the whole annotation system (see the design note in the type-level Javadoc of `DbUnitExpected` on how these resolve). A caching change done carelessly risks a stale-class-level-state bug that would be far worse than the performance cost it's meant to fix.
Impact
Reflection overhead, not a correctness issue - likely on the order of microseconds to low milliseconds per test method; only meaningfully adds up for very large test classes.
Found via
Discovered during a
/code-review highpass onfeat/annotation-driven-setupahead of merging #753, then deliberately deferred rather than forced into a risky restructuring on that branch.