World’s largest virtual agentic engineering & quality conference
Learn how to perform Gherkin testing with this comprehensive guide. Master syntax, scenarios, and best practices for clear, behavior-driven testing.

Salman Khan
Author
Last Updated on: March 17, 2026
On This Page
Gherkin testing is the process of writing and executing tests using the Gherkin language, which is a plain-text, structured format for describing software behavior. It is most commonly used with Behavior-Driven Development (BDD) frameworks like Cucumber or Behave.
Overview
In testing, Gherkin is a simple, structured language used to write test cases in a way that’s easy for both technical and non-technical people to understand.
Syntax of Gherkin File
Feature: User login
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters valid credentials
Then the user should be redirected to the dashboard
Core Keywords and Their Applications
First, a note on the name. A gherkin is a small pickled cucumber, and that is not a coincidence: the language is called Gherkin because it feeds Cucumber, and the compiled test cases it produces are genuinely called Pickles. The naming is a running joke that the maintainers have committed to entirely. If you arrived here looking for the vegetable, this is the wrong page, though you now know the food came first.
The joke aside, these three words get used interchangeably and they are not interchangeable at all. They sit at different levels, and mixing them up is the most common source of confusion for teams adopting BDD.
| Parameters | BDD | Gherkin | Cucumber |
|---|---|---|---|
| What it is | A development methodology | A plain-text language (DSL) | A test execution tool |
| Its job | Align the team on behavior before coding | Write that behavior down unambiguously | Run it as an automated test |
| Tangible form | A practice and a conversation | A .feature file | An installed library or runner |
| Can it run tests? | No, it is a way of working | No, it is a text format | Yes, that is its whole purpose |
| Can you use it alone? | Yes, with no tools at all | Yes, as documentation only | Only with Gherkin to parse |
| Alternatives | TDD, ATDD | Plain prose specs, but you lose automation | SpecFlow, Behave, and others |
The one-line version: BDD is why, Gherkin is what you write, and Cucumber is what runs it.
The last row is worth dwelling on, because it is where the confusion usually pays off. Cucumber is not the only runner that understands Gherkin. SpecFlow does it for .NET, Behave does it for Python, and Cucumber itself has JVM and JavaScript implementations. Gherkin is a language with several interpreters, which is exactly why treating "Gherkin" and "Cucumber" as synonyms causes problems: your .feature files are portable across ecosystems in a way your step definitions are not.
This also answers a question teams ask early: adopting Gherkin does not commit you to Cucumber, and adopting Cucumber does not mean you are doing BDD. Plenty of teams write Gherkin, run it with Cucumber, and never have the conversation that BDD is actually about, which is how you end up with the syntax and none of the benefit.
Gherkin is a plain-text language used to describe software behaviors in a way that’s both human-readable and structured enough for automated testing tools. It’s most commonly associated with frameworks like Cucumber for Behavior-Driven Development.
The main idea is to bridge communication between technical and non-technical team members. Instead of writing complex test scripts, you write simple scenarios that outline what the system should do in specific situations. Java teams practice JBehave testing using the same Given-When-Then structure, with step definitions written directly in Java.
A Gherkin file (usually ending in .feature) is organized into features, scenarios, and steps.
Example:
Feature: User login
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters valid credentials
Then the user should be redirected to the dashboard
Gherkin uses specific keywords to define the role of each line. These keywords can be localized into different languages.
For repetitive scenarios with different inputs, you use Scenario Outline and Examples.
Scenario Outline: Login attempts
Given that the user is on the login page
When the user enters "<username>" and "<password>"
Then the system displays "<message>"
Examples:
| username | password | message |
| alice | pass123 | Welcome, alice! |
| bob | wrong | Invalid credentials|
Use # at the start of a line for comments. They are ignored during execution.
# This is a comment about the scenarioIndentation is optional but recommended for readability. Consistent spacing makes large feature files easier to scan.
A common approach is to indent steps under their corresponding Scenario or Background so the structure is clear at a glance. For example, keeping all Given, When, and Then statements aligned under a scenario title helps distinguish them from higher-level keywords like Feature or Scenario Outline.
Note: Run your Gherkin tests across 3000+ desktop browsers. Try TestMu AI Now!
In Gherkin, the language used to write BDD scenarios, keywords structure the specification so that it is easy to read, consistent, and executable by automation testing tools like Cucumber.
Here are the core Gherkin keywords and how they are applied:
Example:
Feature: User login
Users should be able to log in with valid credentials
Example:
Scenario: Successful login with valid credentials
Example:
Given the user is on the login page
Example:
When the user enters valid credentials
Example:
Then the user should see the dashboard
Example:
And the welcome message is displayed
But the user does not see admin options
Example:
Background:
Given the user is logged in
Example:
Scenario Outline: Login with multiple user roles
Given the user is on the login page
When the user logs in with <username> and <password>
Then the <role> dashboard is displayed
Examples:
| username | password | role |
| alice | pass123 | admin |
| bob | pass456 | member |
Beyond the core keywords, Gherkin has a few advanced constructs that help you make scenarios more expressive, reusable, and maintainable when working on larger test suites.
Here are the main ones and how they are used.
Example:
@smoke @login
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters valid credentials
Then the user should see the dashboard
Example:
When I send the following payload:
"""
{
"username": "alice",
"password": "pass123"
}
"""
Example:
Given the following users exist:
| name | role | active |
| Alice | admin | true |
| Bob | member | false |
Example:
Rule: Only active members can log in
Scenario: Active user logs in successfully
Scenario: Inactive user is denied access
Example:
When the user logs in with username "alice" and password "pass123"
You can write Gherkin for years without knowing this, but it explains several behaviors that otherwise look arbitrary, particularly around Scenario Outlines. A .feature file is not handed to the test runner as text. It goes through a small compilation pipeline first.
The Gherkin parser reads your file and produces an Abstract Syntax Tree (AST), a structured object representing exactly what you wrote: the Feature, its Background, each Scenario, every step, its keyword, any data tables, and the line numbers they came from. This stage is purely structural. It captures your document faithfully, including the parts that are not directly executable, such as descriptions and comments.
This is also where syntax errors surface. A misindented Examples table or an unrecognised keyword fails here, before any test attempts to run, which is why those errors point at a line number rather than at your step definitions.
The AST is then compiled into Pickles, and yes, the name is another link in the Cucumber and Gherkin joke. A Pickle is one clean, executable test case: flattened, with the Background steps already merged in, and stripped of everything the runner does not need.
The detail that actually matters day to day is what happens to a Scenario Outline. In the AST it is a single scenario with an Examples table attached. In the compiler it is expanded, so a Scenario Outline with five rows becomes five separate Pickles, each with the placeholders already substituted.
That is why your test report shows five results rather than one, why a single failing row fails independently of the other four, and why the runner can execute those rows in parallel. By the time anything runs, the Outline no longer exists: there are only concrete test cases.
The separation also explains a piece of architecture. Because Pickles are a plain, language-neutral representation, any runner can consume them. That is precisely how one language serves Cucumber, SpecFlow, and Behave: the parser and compiler are shared, and only the step-definition binding differs per ecosystem.
Because the parser works from a keyword table rather than hardcoded English, Gherkin has built-in localization (i18n) support for more than 70 languages. Add a language header at the top of the file and write the keywords in your own:
# language: fr
Fonctionnalité: Connexion utilisateur
Scénario: Connexion réussie
Soit un utilisateur enregistré
Quand il saisit des identifiants valides
Alors il accède à son tableau de bordThis is not a novelty. The entire premise of BDD is that the specification is readable by the business, and that premise collapses if the business language is not English and the specification is. The step definitions stay in code as usual; only the human-facing layer changes.
Let’s look at the simple Gherkin test written using Selenium and Cucumber that validates the login functionality of TestMu AI eCommerce Playground.
Here is the Gherkin feature file:
Feature: User Login
Scenario: Login with valid credentials
Given the user is on the login page
When the user enters valid credentials
And clicks on the login button
Then the user should be logged in successfully
Below is the test script for the step definitions written using Selenium Cucumber:
package steps;
import io.cucumber.java.en.*;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
public class LoginSteps {
WebDriver driver;
@Given("the user is on the login page")
public void the_user_is_on_the_login_page() throws MalformedURLException {
ChromeOptions options = new ChromeOptions();
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), options);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.get("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
}
@When("the user enters valid credentials")
public void the_user_enters_valid_credentials() {
driver.findElement(By.id("input-email")).sendKeys("testuser@example.com");
driver.findElement(By.id("input-password")).sendKeys("Password123");
}
@When("clicks on the login button")
public void clicks_on_the_login_button() {
driver.findElement(By.cssSelector("input[value='Login']")).click();
}
@Then("the user should be logged in successfully")
public void the_user_should_be_logged_in_successfully() {
String heading = driver.findElement(By.cssSelector("h2")).getText();
if (!heading.contains("My Account")) {
throw new AssertionError("Login failed. Expected My Account page.");
}
driver.quit();
}
}
Code Walkthrough:
Here is how each step in the Gherkin feature file is implemented in the Selenium script during Cucumber testing:
For more information, check this guide on Selenium testing using Gherkin.
Cloud testing platforms such as TestMu AI provides an online Selenium Grid that lets you run Gherkin-based BDD tests at scale across 3000+ real browsers and devices.
With TestMu AI, you can perform Selenium test automation using Cucumber, helping teams validate user stories in plain English while ensuring cross-browser compatibility. This reduces hassles of setting up test infrastructure and accelerates feedback in Agile workflows.
To perform Gherkin testing on TestMu AI, you only need to point your WebDriver to TestMu AI remote grid and configure the automation capabilities. You can generate capabilities from the TestMu AI Automation Capabilities Generator.
ChromeOptions browserOptions = new ChromeOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("dev");
HashMap<String, Object> ltOptions = new HashMap<String, Object>();
ltOptions.put("username", "Your LambdaTest Username");
ltOptions.put("accessKey", "Your LambdaTest Access Key");
ltOptions.put("project", "Gherkin Testing With Selenium");
ltOptions.put("w3c", true);
ltOptions.put("plugin", "java-testNG");
browserOptions.setCapability("LT:Options", ltOptions);Then, replace your LT_USERNAME and LT_ACCESS_KEY with actual values (or set them as environment variables).
Your .feature files and Gherkin scenarios remain unchanged, since TestMu AI only affects the execution environment, not the test logic.
To get started, refer to this guide on Selenium Cucumber testing on TestMu AI.
Gherkin is often sold as an unqualified good, and teams that adopt it on that basis are the ones who abandon it eighteen months later. It has a real payoff and a real cost, and the cost is not obvious on day one.
The honest summary: Gherkin is worth it where a non-technical stakeholder genuinely engages with the scenarios, and where the behavior is complex enough that misunderstanding it is expensive. For everything below that line, particularly unit tests and developer-only suites, it is overhead wearing the costume of rigour.
A .feature file that only runs when someone remembers to run it is documentation, not a test. The living documentation claim only holds if the build enforces it, which means wiring Gherkin into your pipeline.
Mechanically this is simple, because Cucumber and its siblings are command-line runners like any other. The pipeline checks out the code, installs dependencies, and runs the suite. Here is a GitHub Actions workflow:
name: BDD Tests
on:
push:
branches: [ main ]
pull_request:
jobs:
cucumber:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
# run only the scenarios tagged @smoke on every PR
- name: Run Gherkin scenarios
run: mvn test -Dcucumber.filter.tags="@smoke"
# keep the report even when the suite fails
- name: Publish report
if: always()
uses: actions/upload-artifact@v4
with:
name: cucumber-report
path: target/cucumber-reports/The same shape applies to Jenkins or GitLab CI: a stage that runs the runner and archives the report. Two details matter more than the platform. Use tags to split the suite, so @smoke runs on every pull request while the full regression runs nightly, because a BDD suite that adds fifteen minutes to every PR gets disabled. And publish the report with if: always(), since the report you most need is the one from the run that failed.
CI proves the scenarios pass. A Test Management System (TMS) answers a different question: what is our coverage, which requirement does this scenario verify, and what is the trend across releases? Tools such as TestQuality and Testomat.io exist for this, and Gherkin suits them unusually well because a .feature file is already a structured, human-readable test case.
The integration works in both directions, which is the part worth understanding. The TMS imports your .feature files as test cases, so the scenarios developers maintain in Git are the same ones QA leads and stakeholders see. Your CI run then posts results back, so each execution updates the corresponding case automatically instead of someone marking it by hand.
That loop is what makes living documentation more than a slogan. The specification lives in version control where it is reviewed, the pipeline proves it is still true on every commit, and the TMS makes it visible to the people who cannot read a repository. Take away any one of the three and Gherkin reverts to being a verbose way to write tests.
Here are some of the best practices for writing effective Gherkin scenarios that are both readable and maintainable.
If you are using Cucumber, you can follow these Cucumber best practices to write effective Gherkin scenarios.
Here are the common challenges teams face with Gherkin testing, along with practical solutions to address them.
Solution: Use domain language that reflects business processes. Agree on a shared vocabulary with stakeholders and use it consistently across all scenarios.
Solution: Break them into smaller, focused scenarios. One scenario should test one behavior. Use Scenario Outline for variations instead of cramming everything into one.
Solution: Keep backgrounds minimal and only for truly shared, stable setup steps. Any scenario-specific setup should remain in that scenario.
Solution: Write steps at a higher level of abstraction, describing actions in business terms. Let automation code handle the translation to UI interactions.
Solution: Maintain a shared step library and review new steps for reusability before adding them. This keeps the step set small and easier to maintain.
Solution: Be precise about the observable result while keeping the business perspective. For example, “Then the order appears in the pending orders list.”
Solution: Use Gherkin for high-value, business-facing behaviors. Keep unit and integration tests in code where they belong.
Solution: Ensure test data is reset between runs and use stable, dedicated environments for acceptance testing.
Solution: Schedule regular scenario reviews. Treat Gherkin scripts as living documentation, not write-once artifacts.
Gherkin provides a clear and structured way to describe software behavior in plain language while keeping scenarios directly tied to automated tests. By understanding its syntax, keywords, and advanced constructs, teams can write feature files that are both readable and executable. When combined with Selenium, Gherkin becomes a powerful bridge between business requirements and technical implementation, ensuring test coverage aligns with real-world use cases.
Following best practices helps maintain consistency and scalability, while awareness of common challenges prepares teams to resolve issues before they become blockers. In the end, effective use of Gherkin testing fosters better collaboration, improves test automation efficiency, and enhances overall software quality.
Author
Salman is a Test Automation Evangelist and Community Contributor at TestMu AI, with over 6 years of hands-on experience in software testing and automation. He has completed his Master of Technology in Computer Science and Engineering, demonstrating strong technical expertise in software development, testing, AI agents and LLMs. He is certified in KaneAI, Automation Testing, Selenium, Cypress, Playwright, and Appium, with deep experience in CI/CD pipelines, cross-browser testing, AI in testing, and mobile automation. Salman works closely with engineering teams to convert complex testing concepts into actionable, developer-first content. Salman has authored 120+ technical tutorials, guides, and documentation on test automation, web development, and related domains, making him a strong voice in the QA and testing community.
Did you find this page helpful?
More Related Blogs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance