reqnroll-testing
Configures Reqnroll (the canonical .NET BDD framework) - install via `dotnet add package Reqnroll`, author `.feature` files in Gherkin, write step bindings as `[Given/When/Then]`-decorated methods in
Files4
View on GitHubSKILL.mdplugins/qa-bdd/skills/reqnroll-testing/SKILL.md
GitHubreqnroll-testing
Overview
Per reqnroll-home:
"Reqnroll is described as 'an open-source Cucumber-style BDD test automation framework for .NET. It has been created as a reboot of the SpecFlow project.'"
The "reboot" framing is the key: SpecFlow's maintenance slowed in 2023; the community forked into Reqnroll, which has continued active development.
When to use
- A new .NET project starts BDD - pick Reqnroll over SpecFlow.
- An existing SpecFlow project plans to migrate (SpecFlow-compatible; see Step 9).
- The team needs full Gherkin support including Rule blocks (per reqnroll-home: "Full Gherkin support with tagged Rule blocks").
For SpecFlow-locked legacy projects mid-migration (packages, bindings, EOL background), see references/specflow-legacy.md.
Worked example
A checkout team adds one BDD scenario, "Apply valid promo," to a new xUnit project.
dotnet add package Reqnroll.xUnitanddotnet add package Reqnroll.Tools.MsBuild.Generation.Features/Cart.featuredeclares the scenario underRule: Promo codes apply only when valid, withWhen I enter "WELCOME10" in the promo input/Then the subtotal updates to $22.49.Steps/CartSteps.csbinds each line -[When(@"I enter ""([^""]*)"" in the promo input")]calls_page.EnterPromoAsync(code), and theThenassertsAssert.Equal(22.49m, _page.GetSubtotal(), 2).dotnet test --filter "FullyQualifiedName~Cart"runs only that feature.- Result: the scenario turns green, and the MSBuild generator has produced the
runnable test class from the
.featurefile - no glue code beyond the bindings.
Step 1 - Install
# In the test project directory
dotnet add package Reqnroll.xUnit # or Reqnroll.NUnit / Reqnroll.MsTest
dotnet add package Reqnroll.Tools.MsBuild.Generation # generates code from .feature files
Per reqnroll-home: "Works across common operating systems and .NET versions (including .NET 8.0)."
Verify: dotnet build succeeds and restores both packages before you
author features. If code generation does not run, confirm
Reqnroll.Tools.MsBuild.Generation is referenced in the test project.
Step 2 - Author a Feature
# Features/Cart.feature
Feature: Apply promo code at checkout
Background:
Given a logged-in user with email confirmed
And the cart contains 1 of "BOOK-001" at $24.99
Rule: Promo codes apply only when valid
Scenario: Apply valid promo
When I enter "WELCOME10" in the promo input
And I click "Apply"
Then the subtotal updates to $22.49
Scenario Outline: Reject invalid codes
When I enter "<code>" in the promo input
And I click "Apply"
Then an error appears: "<error>"
Examples:
| code | error |
| EXPIRED50 | This code has expired |
| NOTREAL | Code not found |
Rule: blocks (Gherkin 6+) group related scenarios; per
reqnroll-home this is supported.
Step 3 - Step bindings
Write step bindings as [Given/When/Then]-decorated methods in a [Binding]
class. Per reqnroll-home: "Supports flexible step definitions using regex
or cucumber expressions" - regex is more flexible, cucumber expressions
({int}, {string}, {double}) more readable. Full CartSteps binding class
and the cucumber-expression variant:
references/bindings-and-hooks.md.
Step 4 - Async support
Per reqnroll-home: "Async step definitions and hooks."
[Then("the order arrives within (\\d+) minutes")]
public async Task ThenOrderArrives(int minutes)
{
await EmailInbox.WaitForOrderConfirmation(TimeSpan.FromMinutes(minutes));
}
async Task step methods work transparently; no special config.
Step 5 - Hooks
Use [BeforeTestRun], [BeforeScenario] / [AfterScenario], and tag-scoped
hooks (e.g. [BeforeScenario("@browser")]) for setup and teardown; wrap each
scenario in a transaction and roll back in [AfterScenario] so state does not
leak between scenarios. Full hook class:
references/bindings-and-hooks.md.
Step 6 - Tags
@critical @regression
Scenario: Apply valid promo
...
@browser @wip
Scenario: New checkout flow
...
dotnet test --filter "Category=critical"
dotnet test --filter "Category!=wip"
Step 7 - Run
# All tests
dotnet test
# Specific feature
dotnet test --filter "FullyQualifiedName~Cart"
# Generate JUnit XML for CI
dotnet test --logger "junit;LogFilePath=reports/test-results.xml"
If a scenario fails or reports an undefined step, fix the matching binding in
the [Binding] class and re-run until it turns green.
Step 8 - IDE support
Per reqnroll-home: "IDE support for Visual Studio 2022, VS Code, and Rider."
The Reqnroll plugin enables:
- Step navigation (Gherkin → step binding).
- Scaffolding (auto-generate step from undefined Gherkin line).
- Run/debug per-scenario.
Step 9 - Migrate from SpecFlow
Per reqnroll-home: "Compatible with SpecFlow, allowing quick migration of existing projects."
Migration path:
- Replace
SpecFlow.*NuGet packages withReqnroll.*equivalents. - Update
using SpecFlow→using Reqnroll(single find/replace). - Update
[Binding](compatible) and step decorators (mostly compatible). - Run tests; fix any compatibility issues.
Most SpecFlow projects migrate in <1 day for typical scope.
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Starting new .NET BDD with SpecFlow in 2026+ | SpecFlow's maintenance has slowed; Reqnroll is the active fork. | Pick Reqnroll (Step 1). |
| Mixing SpecFlow + Reqnroll in one solution | Two BDD runners; double maintenance. | Migrate everything (Step 9). |
| Regex-only steps when cucumber expressions would work | Less readable; harder to maintain. | Cucumber expressions for typical cases (Step 3). |
No [BeforeScenario] cleanup |
State leaks between scenarios. | Per-scenario hook + transaction rollback (Step 5). |
| Sync step methods that block on async | Deadlocks in xUnit / NUnit / MsTest. | async Task step methods (Step 4). |
Limitations
- Newer than SpecFlow. Some third-party SpecFlow plugins haven't been ported yet.
- Per-test-framework variant. xUnit / NUnit / MsTest each have their own Reqnroll package; pin matching versions.
- Gherkin parser quirks. Some edge cases differ between Reqnroll and Cucumber-JVM; cross-port scenarios need verification.
References
- rh - Reqnroll overview: SpecFlow reboot, Gherkin Rule blocks, SpecFlow-compatible migration, async hooks, IDE support (VS / VS Code / Rider).
- references/bindings-and-hooks.md - full step-binding class, cucumber-expression variant, and hook class.
- references/specflow-legacy.md - legacy SpecFlow support + EOL background + full migration path.
cucumber-testing,behave-testing- sibling language wrappers.bdd-step-library-curator- addresses step proliferation.