Release v4.1.0
Summary
Adds an opt-in execution mode to Cratis.Specifications.XUnit that gives specification classes MSpec-style semantics: construct the class once, run Establish/Because once, run every fact against that shared instance, and run Destroy once after the last fact. Existing consumers see zero change unless they opt in.
Added
- Opt-in shared specification lifecycle for xUnit: add
[assembly: Xunit.TestFramework("Cratis.Specifications.SpecificationTestFramework", "Cratis.Specifications.XUnit")]to a spec assembly and every eligibleSpecificationclass is constructed once, runs Establish/Because once, runs all its facts against that shared instance and runs Destroy once after the last fact (#38) - Automatic fallback to the stock per-fact lifecycle for anything not eligible for sharing - plain xUnit classes, theories,
IDisposablespecifications, and classes using fixtures orITestOutputHelper- so the attribute is safe to add to an existing spec assembly (#38) - Class-fixture-style failure semantics in shared mode: a throwing Establish/Because fails every fact of the class with that exception, and Destroy failures surface as test class cleanup failures (#38)
Changed
Specification.InitializeAsyncis now idempotent - Establish/Because run only on the first call per instance. Stock xUnit calls it exactly once per instance, so behavior without the opt-in is unchanged (#38)