From e9e6269dc8b8eaec0605665b2f2a0153e9313797 Mon Sep 17 00:00:00 2001 From: Edwin van den Houdt Date: Thu, 4 Jun 2026 11:17:22 +0200 Subject: [PATCH] =?UTF-8?q?docs(architecture):=20ADR-0004=20=E2=80=94=20Re?= =?UTF-8?q?qnroll=20as=20BDD=20framework=20(refs=20#5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- docs/architecture/adr-0004-bdd-framework.md | 52 +++++++++++++++++++++ mkdocs.yml | 3 ++ 2 files changed, 55 insertions(+) create mode 100644 docs/architecture/adr-0004-bdd-framework.md diff --git a/docs/architecture/adr-0004-bdd-framework.md b/docs/architecture/adr-0004-bdd-framework.md new file mode 100644 index 0000000..546b72e --- /dev/null +++ b/docs/architecture/adr-0004-bdd-framework.md @@ -0,0 +1,52 @@ +# 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. diff --git a/mkdocs.yml b/mkdocs.yml index 6f4e752..92e4c5b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -23,6 +23,9 @@ nav: - Product Requirements: PRD.md - Architecture: - "ADR-0001: Loose coupling": architecture/adr-0001-loose-coupling.md + - "ADR-0002: Catalogus design": architecture/adr-0002-catalogus-design.md + - "ADR-0003: ACL default-fill": architecture/adr-0003-default-fill.md + - "ADR-0004: BDD framework": architecture/adr-0004-bdd-framework.md - Working in Gitea: gitea-workflow.md - Runbooks: - CI: runbooks/ci.md