Record the choice of Reqnroll.xUnit for the acceptance layer introduced in S-04, and register the previously-unlisted ADR-0002/0003 in the MkDocs nav. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
2.8 KiB
Markdown
53 lines
2.8 KiB
Markdown
# ADR-0004: Reqnroll as the BDD acceptance framework
|
|
|
|
- **Status:** Accepted
|
|
- **Date:** 2026-06-04
|
|
- **Deciders:** Respellion engineering
|
|
- **Relates to:** S-04 (#5); supports CLAUDE.md §3 (BDD at the use-case level) and §11 (tests pyramid)
|
|
|
|
## Context
|
|
|
|
CLAUDE.md §11 mandates that each user-visible flow is driven by a Gherkin acceptance
|
|
scenario living in `tests/acceptance/`, and §3 names "BDD at the use-case level" as a core
|
|
engineering principle. The foundational slices (S-00…S-03) added no acceptance layer; S-04
|
|
is the first slice with real domain behaviour to drive, so it is where the BDD framework is
|
|
introduced. We need a .NET tool that:
|
|
|
|
- parses Gherkin `.feature` files and binds steps to C#,
|
|
- integrates with the existing xUnit test runner (the repo standardises on xUnit), so
|
|
acceptance tests run under the same `dotnet test` / `make ci` gate as everything else,
|
|
- is actively maintained on modern .NET (we target net10.0).
|
|
|
|
## Decision
|
|
|
|
**Use [Reqnroll](https://reqnroll.net/) (`Reqnroll.xUnit`) for acceptance tests.**
|
|
|
|
- Reqnroll is the actively-maintained, open-source successor to SpecFlow (which is no longer
|
|
maintained). It keeps the same Gherkin + `[Binding]` model, so the knowledge transfers.
|
|
- `Reqnroll.xUnit` generates one xUnit test per scenario, so acceptance tests are discovered
|
|
and run by the same runner as the unit tests — no second test framework, no extra CI step.
|
|
- Acceptance projects live under `tests/acceptance/` per the PRD §9 layout. Generated
|
|
`*.feature.cs` files are build artefacts and are git-ignored.
|
|
|
|
## Consequences
|
|
|
|
- **Positive:** one assertion/runner stack (xUnit) across unit and acceptance tests; scenarios
|
|
are written in business language (Dutch domain terms inline) and reviewed as the slice's
|
|
contract; maintained tooling on net10.0.
|
|
- **Cost:** a new dependency (`Reqnroll.xUnit`) and its xUnit v2 transitive graph. Reqnroll
|
|
pulls `xunit.core` but not the assertion library, so the `xunit` metapackage is referenced
|
|
explicitly to get `Assert`.
|
|
- **Replaceable by:** hand-written xUnit "scenario" tests with a Given/When/Then helper, at
|
|
the cost of losing Gherkin as the shared, readable contract — which is the whole point of §3.
|
|
- **Follow-ups:** the real-OpenZaak integration test (Testcontainers) and the Stryker mutation
|
|
baseline for S-04 are tracked as their own issues split off #5.
|
|
|
|
## Alternatives considered
|
|
|
|
- **SpecFlow** — rejected: unmaintained and without an official net10.0 story; Reqnroll is its
|
|
drop-in successor.
|
|
- **Plain xUnit Given/When/Then helpers** — rejected for user-visible flows: loses the
|
|
business-readable Gherkin contract that §3/§11 require. Still fine for unit-level tests.
|
|
- **Xunit.Gherkin.Quick** — rejected: lighter but less featureful (no hooks/scoped contexts,
|
|
smaller community) than Reqnroll.
|