Skip to content

Example Gherkin-to-CSharp Step Definitions

The following uses Reqnroll examples, however this is idential when using SpecFlow.

Here’s a clear, practical explanation of how Gherkin feature files map to C# step definitions (using SpecFlow/Reqnroll, since Reqnroll is the modern fork of SpecFlow).


Basic Gherkin → C# Mapping

Gherkin (Feature File)

Feature: Calculator
  In order to avoid silly mistakes
  As a maths student
  I want to use a calculator

  Scenario: Add two numbers
    Given I have entered 50 into the calculator
    And I have entered 70 into the calculator
    When I press add
    Then the result should be 120

C# Step Definitions (Reqnroll/SpecFlow)

using Reqnroll;

[Binding]
public class CalculatorSteps
{
    private readonly Calculator _calculator = new();
    private int _result;

    [Given(@"I have entered (.*) into the calculator")]
    public void GivenIHaveEnteredNumber(int number)
    {
        _calculator.Enter(number);
    }

    [When(@"I press add")]
    public void WhenIPressAdd()
    {
        _result = _calculator.Add();
    }

    [Then(@"the result should be (.*)")]
    public void ThenTheResultShouldBe(int expected)
    {
        Assert.Equal(expected, _result);
    }
}

Notes

  • Step attributes: [Given], [When], [Then] map directly to steps in the Gherkin file.
  • Regex patterns inside the attributes capture values from the Gherkin step.
  • Step classes must be decorated with [Binding].

Example with Tables

Gherkin

Scenario: Create a user
  Given I enter the following details
    | Name  | Age |
    | Mark  | 30  |
  When I submit the form
  Then the user should be created

C# Step Definition

[Given(@"I enter the following details")]
public void GivenIEnterDetails(Table table)
{
    var user = table.CreateInstance<User>();
    _context.User = user;
}

Reqnroll/SpecFlow automatically binds the table to a C# object using the headers.

Example with Scenario Outline

Gherkin

Scenario Outline: Multiplying numbers
  Given I have entered <x> into the calculator
  And I have entered <y> into the calculator
  When I press multiply
  Then the result should be <result>

  Examples:
    | x | y | result |
    | 2 | 3 | 6      |
    | 4 | 5 | 20     |

C# Step Definitions

Same as before — the placeholders are just passed into the regex.

Tips for Structuring Steps in C#

  • Use step re-use to avoid repetition - If two Gherkin steps are similar, make one step regex broader.
  • Keep logic out of step definitions - Steps should call into domain/service classes.
  • Use DI - Reqnroll supports dependency injection via constructor injection in [Binding] classes.
  • Avoid over-matching regex - Prefer explicit patterns:
[Given(@"I have entered (\d+) into the calculator")]

Drawbacks & Common Mistakes

Issue Description
Overuse of regex Makes steps fragile and hard to read.
Putting business logic inside step definitions Leads to duplication and hard-to-maintain automation code.
Too many step definitions Good Gherkin design avoids repeating the same sentence many times.
Using steps like UI scripts Steps should be behaviour-oriented, not pixel-oriented.