| Property | Value |
|---|---|
| Category | Reproducibility (JustDummies.Reproducibility) |
| Severity | 🔵 Info |
| Enabled by default | Yes |
A static AnyContext looks maximally deterministic — a literal seed, right there in the source — and is not. AnyContext’s own documentation states the hazard:
A context is safe to draw from concurrently, but sharing one across threads costs the replay rather than the values: interleaved draws make neither the sequence nor the multiset stable across runs. Keep a context to one thread at a time.
So in a suite that runs its classes in parallel, each test gets whatever the interleaving happened to hand it. The seed is pinned and the run still does not replay.
Noncompliant
private static readonly AnyContext Context = Any.WithSeed(1234); // JD020
Compliant
// One context per unit of work…
AnyContext context = Any.WithSeed(1234);
// …or the ambient scope, which flows with the execution context:
using IDisposable scope = Any.UseSeed(1234);
What it does not flag
- An instance context, which is per-test by construction.
- A static field holding a generator: the random source is resolved at
Generate()time, never at construction, so a shared recipe is safe and idiomatic.
Info rather than Warning: a single-threaded consumer — a console sample, a benchmark, a [Collection]-serialised class — shares one harmlessly, and the rule cannot see the suite’s parallelism configuration.