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 any C# class, runs via `dotnet test`. Reqnroll is the SpecFlow successor (originated as a community port off the SpecFlow codebase); new .NET BDD work targets Reqnroll. Use for .NET projects starting BDD or migrating from SpecFlow.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Full step-binding and hook examples for reqnroll-testing (Steps 3 and 5).
// Steps/CartSteps.cs
using Reqnroll;
using Xunit;
[Binding]
public class CartSteps
{
private CheckoutPage _page;
private Cart _cart;
[Given("a logged-in user with email confirmed")]
public async Task GivenLoggedInUser()
{
var user = await TestUsers.LoggedInWithEmailConfirmed();
_page = new CheckoutPage(user);
}
[Given(@"the cart contains (\d+) of ""([^""]*)"" at \$(\d+\.\d+)")]
public void GivenCartContains(int qty, string sku, decimal price)
{
_cart = new Cart();
_cart.AddItem(new Item(sku, qty, price));
_page.SetCart(_cart);
}
[When(@"I enter ""([^""]*)"" in the promo input")]
public async Task WhenIEnter(string code)
{
await _page.EnterPromoAsync(code);
}
[When(@"I click ""([^""]*)""")]
public async Task WhenIClick(string label)
{
await _page.ClickAsync(label);
}
[Then(@"the subtotal updates to \$(\d+\.\d+)")]
public void ThenSubtotalUpdates(decimal expected)
{
Assert.Equal(expected, _page.GetSubtotal(), 2);
}
}Per reqnroll-home: "Supports flexible step definitions using regex or cucumber expressions." The example uses regex; cucumber expressions are an alternative:
[Given("the cart contains {int} of {string} at ${double}")]
public void GivenCartContains(int qty, string sku, double price) { ... }Cucumber expressions are more readable; regex is more flexible.
using Reqnroll;
[Binding]
public class TestHooks
{
[BeforeTestRun]
public static async Task BeforeTestRun()
{
// Once per test run
await TestDatabase.Initialize();
}
[BeforeScenario]
public async Task BeforeScenario()
{
// Per-scenario
await TestDatabase.StartTransaction();
}
[AfterScenario]
public async Task AfterScenario(ScenarioContext context)
{
await TestDatabase.Rollback();
if (context.TestError is not null)
{
await ScreenshotCapture.Capture(context.ScenarioInfo.Title);
}
}
[BeforeScenario("@browser")]
public async Task BeforeBrowserScenario()
{
// Tag-scoped hook
await Browser.LaunchAsync();
}
}