Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

This SpecFlow automation tutorial demonstrates how a BDD test can be written using SpecFlow and Selenium C# and run it on the cloud Selenium Grid like TestMu AI with SpecFlow Actions.
January 13, 2026
With the rise of Agile, teams have been trying to minimize the gap between the stakeholders and the development team.
Behavior Driven Development, or BDD, is a great way to bring together technical and non-technical folks by focusing more on the behavior of the apps, and a good understanding of the requirements, from a behavioral perspective.
SpecFlow is a Behavior-Driven Development (BDD) framework for .NET that helps teams automate testing using plain, human-readable language. It bridges the gap between business stakeholders and developers by turning feature requirements written in Gherkin syntax into executable test scripts.
How SpecFlow Automation Works
Gherkin Feature Files: You define scenarios using keywords like Given, When, and Then to describe user behavior.
This setup allows teams to create living documentation that evolves alongside the codebase, ensuring both clarity and test accuracy.
SpecFlow Actions for Simplified Automation
SpecFlow Actions are a collection of pre-built NuGet packages that make automation faster and easier. They handle setup and configuration for tools like Selenium, Appium, and REST APIs, reducing repetitive coding tasks.
For example, using SpecFlow.Actions.Selenium, you can quickly run web tests without manually configuring WebDriver, improving test reliability and speed.
Benefits of Using SpecFlow
Enhances collaboration between teams using a shared Gherkin syntax.
BDD is centered on explicitly defining a feature’s desired behavior from the beginning. Specification by example is a method for identifying behaviors that use concrete examples rather than abstract, general language to describe the intended behavior. They act as the product’s requirements/acceptance criteria (before development) and test cases (after development).
In this SpecFlow automation tutorial, I’ll demonstrate how a BDD web test can be written using SpecFlow and Selenium C# and how to run it on the cloud Selenium Grid with SpecFlow Actions. I am using Visual Studio 2022, but you can use an older version to follow along. If you are preparing for an interview you can learn more through SpecFlow interview questions.
BDD is built on TDD (Test-driven development), which makes it an approach where tests are written first.
Since BDD is a collaborative approach, the product owner (stockholder), developers, project managers, QAs, and user acceptance testers come together to discuss which test scenarios should be passed to consider this software/application successful. They create a set of test scenarios in this way.
Since all of these test scripts are written in plain English, they also serve as documentation for the project. SpecFlow is a framework for defining these scenarios in a more structured way and tying them to tests that run against the code.
These two approaches—in isolation and together—can help you write better code and provide higher-quality software faster.
Cucumber is one of the most important tools that support BDD. It provides a means to write tests everyone can understand regardless of their technical skills.
Cucumber reads plain language executable specs and verifies that the program performs what it is supposed to. The specifications provide several scenarios. For example:
Scenario: We only work on weekdays
Given today is Sunday
When I get up
Then I don’t have to work
Each scenario consists of a series of actions that the Cucumber must perform. Cucumber checks whether the program matches the specification and produces a report stating if each scenario was successful or unsuccessful.
The Cucumber files use the extension .feature, and the scenarios must follow syntax rules called Gherkin. The lines in Gherkin should start with keywords.
The most important keywords in Gherkin are:
SpecFlow is a BDD automation framework for .NET that uses the Gherkin language. It is provided as a Visual Studio extension. While writing this SpecFlow automation tutorial, the latest SpecFlow version is 3.9, released in November 2021.
SpecFlow uses the official Gherkin parser, with support for over 70 languages – which means that you can write your Given/When/Then scenarios in languages other than English, too. Then, using bindings, these tests are connected to the application code, enabling you to run the tests using the testing framework of your choice (such as NUnit, in our case).

To use SpecFlow, you need to install the Visual Studio extension. That can be easily done from the Visual Studio → Extension menu → Manage extensions, and search for SpecFlow. Then, to create a new SpecFlow project, from the New Project wizard, select the SpecFlow Project type:

Choose a target framework and your preferred test automation framework and complete the wizard. In this SpecFlow automation tutorial, we’ll be using NUnit from here on, and I’ll explain along the way the NUnit methods.
Subscribe to the TestMu AI YouTube Channel to see our latest tutorials about Selenium automation, Appium automation, Playwright automation, and more.
By default, the project will have a Features folder containing a file with the .feature extension and a StepDefinitions folder, which includes the implementations of the features:

SpecFlow Actions is a solution provided by SpecFlow that enables us to integrate our SpecFlow tests with Selenium. It manages the browser’s lifetime and offers simple configuration options and Selenium helper methods.
The aim is to address typical issues testers run into when automating websites, applications, or APIs, such as working with multiple browsers or always being up-to-date with the latest browser version.
In the upcoming sections of this SpecFlow automation tutorial, I will walk you through the steps you need to integrate SpecFlow Actions with continuous testing clouds like TestMu AI to run tests in parallel on an online browser farm of 3000+ real browsers, devices, and OS.
Note: Run C# Automation Testing Online. Try TestMu AI Now!
Before starting with SpecFlow automation, follow the steps above to install the SpecFlow extension and create a new SpecFlow project.
Next, you’ll need to install the following NuGet packages:
There are more ways to install a NuGet package. You can do it from the NuGet Package Manager of the project:

Or you can use the NuGet Package Manager Console (Tools → NuGet Package Manager → Package Manager Console, and run the command:
dotnet add <PROJECT> package [options] <PACKAGE_NAME>
For example:
dotnet add package Selenium.WebDriver --version 3.141.0
Now the project should look like this:

{
"selenium": {
"defaultTimeout": 60,
"pollingInterval": 5,
"lambdatest": {
"url": "https://${LT_USERNAME}:${LT_ACCESS_KEY}@hub.lambdatest.com/wd/hub"
}
}
}

I can use a specific browser version by providing the exact version number, instructing SpecFlow Actions to use the latest version, or telling it to go back to a certain number of versions.
Let me illustrate that. Here is the specflow.actions.windows10.firefox.json file, where I am using the latest version of Firefox:
{
"selenium": {
"browser": "Firefox",
"capabilities": {
"platform": "Windows 10",
"version": "latest",
"build": "[Demo - 2] SpecFlow Actions on LambdaTest",
"project": "SpecFlow Actions Demo",
"selenium_version": "3.141.59"
}
}
}
And the specflow.actions.windows11.chrome.json file, where I am using the 4th latest version of Chrome:
{
"selenium": {
"browser": "Chrome",
"capabilities": {
"platform": "Windows 11",
"version": "latest-4",
"build": "[Demo - 1] SpecFlow Actions on LambdaTest",
"project": "SpecFlow Actions Demo",
"selenium_version": "3.141.59"
}
}
}
Most of the browser capabilities are optional, but they are helpful when you need specific configurations or want to personalize the results, for example with the build and project names.
You can use the same capabilities you would obtain using the TestMu AI Automation Capabilities Generator, but in JSON format:

I’ll use a fairly simple scenario to demonstrate how to write a BDD test scenario using SpecFlow.Actions with Selenium in C#. The test will be:

The .feature file contains the test scenarios written using the Gherkin language. I am testing two scenarios – see how easy they are to read:
Feature: ECommerce Playground Demo
@searchItems
Scenario: Search for iPod Nano
Given I select the Software category
When I search for iPod Nano
Then I should get 4 results for iPod Nano
@searchItems
Scenario: Search for HTC Touch HD
Given I select the Tablets category
When I search for HTC Touch HD
Then I should get 8 results for HTC Touch HD
The class containing the implementation (I named it SearchItemsStepDefinitions.cs) of the steps should look like this:
using NUnit.Framework;
using OpenQA.Selenium;
using SpecFlow.Actions.Selenium;
using TechTalk.SpecFlow;
[assembly: Parallelizable(ParallelScope.Fixtures)]
[assembly: LevelOfParallelism(4)]
namespace LTSpecFlow.StepDefinitions
{
[Binding]
public class AddItemsToCartStepDefinitions
{
private readonly IBrowserInteractions _browserInteractions;
public AddItemsToCartStepDefinitions(IBrowserInteractions browserInteractions)
{
_browserInteractions = browserInteractions;
}
[BeforeScenario]
public void SetUp()
{
_browserInteractions.GoToUrl("https://ecommerce-playground.lambdatest.io/");
}
[Given(@"I select the (.*) category")]
public void GivenISelectTheCategory(string category)
{
_browserInteractions.WaitAndReturnElement(By.XPath("(//div[@class='dropdown search-category']/button[@type='button'])[1]")).Click();
_browserInteractions.WaitAndReturnElement(By.XPath($"(//a[text()='{category}'])[1]")).Click();
}
[When(@"I search for (.*)")]
public void WhenISearchForProduct(string product)
{
_browserInteractions.WaitAndReturnElement(By.XPath("(//input[@name='search'])[1]")).SendKeys(product);
_browserInteractions.WaitAndReturnElement(By.XPath("(//button[normalize-space()='Search'])[1]")).Click();
}
[Then(@"I should get (.*) results for (.*)")]
public void ThenIShouldGetResults(int itemsCount, string product)
{
int actualCount = _browserInteractions.WaitAndReturnElements(By.XPath($"//div[@class='row']//div[@class='carousel-item active']/img[@alt='{product}']")).Count();
Assert.AreEqual(itemsCount, actualCount);
}
}
}
Let’s begin with the feature file. Each feature file should, ideally, test only one feature of the application. This is defined by the “Feature” keyword, which should be the file’s first line. In my case, I am testing website’s search functionality, so the name I gave to the feature is “Search products”:
Feature: Search products
Next, before my test scenario, I added a tag. These tags are used to identify and group related scenarios or scenarios that will be run together at some point.
@searchItems
One scenario can have multiple tags, for example:
@SmokeTests @RegressionTests @FunctionalityTests
Next comes the actual test scenario:
@searchItems
Scenario: Search for iPod Nano
Given I select the Software category
When I search for iPod Nano
Then I should get 4 results for iPod Nano
It’s written in plain English and uses the Gherkin keywords:
The beauty here is that the entire test is extremely easy to read by anybody, not just technical people or automation testers. And also, anybody can write this type of scenario without understanding the inner workings of a test automation framework.
And thanks to the SpecFlow extension, for any new Gherkin steps written, you can generate the code steps, by right-clicking on the steps and selecting Define steps. You’ll get something like this:

Then you’ll have to write the implementation for the steps. This brings us to the Steps Definition class. The first part contains the packages used in the class:
using NUnit.Framework;
using OpenQA.Selenium;
using SpecFlow.Actions.Selenium;
using TechTalk.SpecFlow;
We are using Selenium, SpecFlow, SpecFlow Actions, and NUnit, which I use for the test’s assertions.
Then, using NUnit’s Parallelizable attribute, I define that 4 tests from the same assembly can run in parallel (so all the tests from the example, since we have 2 tests and 2 browser configurations). To learn more about parallel execution with SpecFlow, NUnit, and Selenium, please go through the following video:
[assembly: Parallelizable(ParallelScope.Fixtures)]
[assembly: LevelOfParallelism(4)]
Now comes the actual implementation. The [Binding] attribute marks the class as a step implementation class.
The first thing you need to do is create a constructor, and instantiate an IBrowserInteractions variable (this is the SpecFlow Actions equivalent of Selenium’s IWebDriver):
private readonly IBrowserInteractions _browserInteractions;
public AddItemsToCartStepDefinitions(IBrowserInteractions browserInteractions)
{
_browserInteractions = browserInteractions;
}
Next, use the [BeforeScenario] hook, which marks the following method to run before each scenario. I prefer using this type of hook instead of writing an explicit Gherkin step for starting the app because, while this step is mandatory before any other steps, I don’t find that it reflects a part of the user behavior:
[BeforeScenario]
public void SetUp()
{
_browserInteractions.GoToUrl("https://ecommerce-playground.lambdatest.io/");
}
The following methods will be the test steps. For each method to be bound to the correct feature step, it needs to have a matching attribute (Given / When / Then), followed by a regular expression that matches the Gherkin step. For example, the
[Given(@"I select the (.*) category")]
Regular expression matches both
Given I select the Software category
and
Given I select the Tablets category
The (.*) pattern means that my expression will match any value. Then the method needs to have a parameter of the relevant type – string in this case, and int and string in the last step.
I should get (.*) results for (.*)
The actual implementation is fairly similar to a Selenium implementation, except this time we are using the methods provided by SpecFlow Actions. To identify elements, you need to use WaitAndReturnElement (for a single element) and WaitAndReturnElements (for a list of elements), and then to interact with them, you can use Click() and SendKeys() – the same way you would if you would use Selenium WebDriver.
For this particular SpecFlow automation tutorial, I used the XPath locator for the web elements on the page because the web elements do not have unique IDs. XPath is one of the most used locators in Selenium WebDriver for navigating across a page’s HTML structure. Any element on a web page can be located using the HTML DOM framework for both HTML and XML documents.
The basic fundamental format of an XPath is:
//tagname[@attribute=’value’]
Where:
To get the elements’ XPath, you can use the Developer Tools provided by the browser (right-click on the element and select Inspect) and build it based on its attributes.
You can even select Copy → XPath, although this might not always return the best XPath or even a unique one. You can also use Chrome extensions that help identify the best locator for web elements, I use and recommend SelectorsHub:
You can use the Console to see how many elements are returned for a specific XPath:

You can use the Console to see how many elements are returned for a specific XPath:


So what you need to do is:
[Given(@"I select the (.*) category")]
public void GivenISelectTheCategory(string category)
{
_browserInteractions.WaitAndReturnElement(By.XPath("(//div[@class='dropdown search-category']/button[@type='button'])[1]")).Click();
_browserInteractions.WaitAndReturnElement(By.XPath($"(//a[text()='{category}'])[1]")).Click();
}
[When(@"I search for (.*)")]
public void WhenISearchForProduct(string product)
{
_browserInteractions.WaitAndReturnElement(By.XPath("(//input[@name='search'])[1]")).SendKeys(product);
_browserInteractions.WaitAndReturnElement(By.XPath("(//button[normalize-space()='Search'])[1]")).Click();
}
[Then(@"I should get (.*) results")]
public void ThenIShouldGetResults(int itemsCount)
{
int actualCount = _browserInteractions.WaitAndReturnElements(By.XPath("//div[@class='carousel-item active']")).Count();
Assert.AreEqual(itemsCount, actualCount);
}
Here, you can use the Assert class from NUnit to compare two values. If the values are equal, the test will pass; if not, the test will fail.
And that’s all! Now let’s put our tests to work!
Note: Accelerate C# Automated Scripts with Parallel testing. Try TestMu AI Now!
You will be able to see the tests in Test Explorer (Test → Test Explorer), just like in any other Visual Studio Project:

The number of tests will match the number of scenarios defined in the feature file(s) times the number of browser configurations. In this SpecFlow automation tutorial, I have 2 scenarios and 2 browser configurations, so I’ll see 4 tests in the explorer window. The Traits column is populated with the tags I used for the scenarios.
Now, if you press Run All, you’ll see that the tests start executing, and if you define the parallelization, they will run in parallel. No browser window will open since we’re running the tests on the cloud. Still, you can see the tests running on the TestMu AI Dashboard:

Once they finish running, you can see them in your TestMu AI account, in Automation → Builds:

To see the details, you can click on each test, where you will find a video recording of the test run, the configuration details, the time it took for the test to run, its result, and the step details with each of their results. You can also click on each step to see the recording at that exact time:

Are you a tester looking to hone your skills? Prove your worth by earning the Selenium C# 101 certification by TestMu AI.

Deliver immersive digital experiences with Next-Generation Mobile Apps and Cross Browser Testing Cloud
In this Selenium C# tutorial, we have seen why SpecFlow is an excellent framework for writing behavior-driven scenarios because the tests can be written in simple English and understood by anyone on the team.
And on top of this, using SpecFlow Actions can power up your test automation even further since it enables you to run the tests on various browser versions and operating systems and run them in parallel on the Selenium IDE cloud. With TestMu AI, you can enhance your SpecFlow testing by running SpecFlow tests on the cloud, allowing for greater scalability and collaboration among distributed teams.
Author
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance