A product manager says, “Customers should be able to use a discount code.” A developer starts building the discount calculation. A tester asks, “What if the code has expired? Does it apply before tax?” The team may think it agrees on the feature, but those unanswered questions can produce very different results.
Gherkin helps teams describe expected software behavior as concrete, readable examples. It uses keywords such as Feature, Scenario, Given, When, and Then to structure the examples. A tool such as Cucumber can connect those steps to test code. Writing a Gherkin file by itself does not automate a test.
Feature: Discount codes
Scenario: Apply a valid fixed-amount code
Given the cart has eligible items worth $50
And the customer has a valid code for $10 off
When the customer applies the code
Then the eligible subtotal should be $40
The example establishes the starting situation, the action, and the expected result. It also exposes a useful question: is the $40 amount a subtotal before tax and shipping? A team can resolve that question before code is written.
What is Gherkin used for?
Gherkin is commonly used to express acceptance criteria in behavior-driven development (BDD). Product, development, and testing colleagues discuss a business rule and capture specific examples of how it should behave. The examples can guide development, software testing , and conversations about requirements within the software development life cycle .
A .feature file can be useful documentation even when its scenarios are not automated. If the team connects its steps to code, it can also be an executable specification. In either case, the file is only useful while it reflects the product's current behavior.
Gherkin is a domain-specific language, not a general-purpose programming language. It describes behavior rather than implementing application logic. It is also distinct from Cucumber: Gherkin is the syntax; Cucumber is a tool that reads that syntax and runs matching step definitions. See the official Gherkin reference for the full grammar.
How to read a Gherkin feature file
A file typically has the .feature extension and starts with Feature:. It contains one or more scenarios, each illustrating a specific example.
Feature: Discount codes
Customers can reduce the cost of eligible orders.
Rule: Expired codes cannot be applied
Scenario: Reject a code after its expiry date
Given the cart has eligible items worth $50
And the code "OLD10" expired yesterday
When the customer applies "OLD10"
Then the eligible subtotal should remain $50
And the customer should see an expiry message
Feature names the capability. The optional Rule groups examples of one business rule. Scenario gives a particular example. Given establishes context, When identifies an action or event, and Then states an observable outcome. And continues the preceding kind of step; But can express a contrast.
|
Keyword |
Purpose |
Example |
|---|---|---|
|
Feature: |
Groups related behavior |
Feature: Discount codes |
|
Rule: |
Groups examples of a business rule |
Rule: Expired codes cannot be applied |
|
Scenario: or Example: |
Introduces one example |
Scenario: Reject an expired code |
|
Given |
Sets the starting context |
Given the cart has eligible items worth $50 |
|
When |
Names an action or event |
When the customer applies "OLD10" |
|
Then |
Names an expected outcome |
Then the code should be rejected |
|
And / But |
Adds another step |
And the total should remain unchanged |
The heading keywords take a colon; Given, When, and Then do not. Gherkin supports localized keywords in many spoken languages. These examples use English.
What do Given, When, and Then mean?
Think context → event → outcome . A good Then makes the result clear to someone who uses the system or consumes its output. “Then everything works” says too little. “Then the customer sees that the code has expired and the subtotal remains $50” is something the team can actually check.
The syntax cannot fix a vague requirement on its own. Its value comes from discussing the example and agreeing on what it means.
Complete example: Valid and expired discount codes
Here is a small feature with two business rules:
Feature: Apply a discount code
Customers can apply one eligible code to their cart.
Rule: Valid codes reduce the eligible subtotal
Scenario: Apply a valid fixed-amount code
Given the cart has eligible items worth $50
And the code "SAVE10" offers $10 off
When the customer applies "SAVE10"
Then the eligible subtotal should be $40
And the cart should show "SAVE10" as applied
Rule: Expired codes do not change the subtotal
Scenario: Reject an expired code
Given the cart has eligible items worth $50
And the code "OLD10" has expired
When the customer applies "OLD10"
Then the eligible subtotal should remain $50
And the customer should see an expiry message
Notice the word eligible . These examples say nothing about whether tax, delivery fees, or excluded products receive a discount. If those decisions matter, the team should specify them in additional rules and examples. Concrete scenarios are useful precisely because they reveal assumptions.
These examples can help with test case design in the software testing life cycle . They do not replace exploratory checks or other software testing techniques .
How does Gherkin work with Cucumber?
Cucumber reads the feature file and finds a matching step definition for each step. A step definition is code that prepares data, performs an action, or verifies an outcome. Here is one illustrative definition in Cucumber for JavaScript:
const { Then } = require('@cucumber/cucumber');
const assert = require('node:assert/strict');
Then('the eligible subtotal should be ${int}', async function (expected) {
const actual = await this.cart.getEligibleSubtotal();
assert.equal(actual, expected);
});
This is one piece of an example, not a runnable project on its own . It assumes the test project provides this.cart and definitions for the other steps. Cucumber matches the sentence, executes the code, and reports whether the assertion passes. A missing matching step definition leaves that automated scenario incomplete.
Keep the business rule readable in the feature file and put selectors, API calls, and other mechanics in the step definitions. If the feature file reads like a click-by-click script, product colleagues may struggle to review it, and a small interface change may require rewriting many scenarios. The Cucumber step organization guide explains how to organize reusable definitions. Gherkin is one part of a broader software testing toolset .
Scenario Outline and Examples: Same behavior, different inputs
Use Scenario Outline when the same rule should be checked with several sets of data. Text inside angle brackets is replaced by values in the Examples table. Each row becomes a separate scenario run.
Feature: Sign-in validation
Scenario Outline: Reject an invalid email address
Given a visitor is on the sign-in page
When the visitor enters "<email>" as the email address
Then the form should show "Enter a valid email address"
Examples:
| email |
| missing-at |
| name@ |
Both inputs should produce the same kind of result, so an outline makes sense. If one case has a different business outcome, a separate scenario may be easier to understand. Avoid huge Examples tables that turn a readable specification into a spreadsheet.
Background, data tables, doc strings, and tags
- Background: defines setup shared by scenarios in its scope. Keep it short so readers do not have to scroll far to understand each scenario.
- Data tables pass structured data to a single step. They are different from Examples, which generates multiple runs from a scenario outline.
- Doc strings provide multiline input to one step, such as a message or JSON payload.
- Tags , such as @smoke, label features or scenarios for organization and, depending on the runner, selective execution.
This table is input to one Given step:
Scenario: Apply a code to an eligible cart
Given the cart contains these products:
| product | price |
| Notebook | 20 |
| Pen set | 10 |
When the customer applies an eligible $5 code
Then the eligible subtotal should be $25
A step definition must interpret those rows and create the cart. The table does not automatically populate the application. The official reference has the precise rules for tables, doc strings, tags, and scope.
How to write useful Gherkin scenarios
- Start with a real disagreement or risk. Ask what should happen for a normal case, a meaningful boundary, and a failure case.
- Name the outcome. “Reject an expired code” communicates more than “Test discount 2.”
- Keep each scenario focused. A scenario that covers registration, payment, refunds, and email delivery is hard to diagnose when it fails.
- Use concrete values where they clarify the rule. A $50 subtotal and $10 discount expose more assumptions than “some cart” and “a code.”
- Describe an observable result. Prefer a user-visible message or documented API response over an incidental implementation detail.
- Keep steps reusable without making them meaningless. Generic phrases such as “When the user does the action” save little and hide intent.
- Update examples when behavior changes. A green automated test against an obsolete requirement can mislead the team.
The right level of detail depends on the audience. A high-level customer scenario may omit interface mechanics, while an API contract scenario may reasonably specify a response status and field. What matters is that the people involved agree on the intended behavior.
Benefits and limitations of Gherkin
|
It helps when... |
Be careful when... |
|---|---|
|
Product, development, and QA need a shared example |
Requirements remain vague despite readable formatting |
|
Business rules need reviewable acceptance criteria |
Automation cost outweighs the value of repeating the check |
|
Important behaviors need repeatable regression checks |
UI-heavy tests become slow and brittle |
|
New teammates need to understand expected behavior |
Feature files are allowed to drift from the product |
You do not need Gherkin for every test. A small calculation may be simpler to verify with a unit test. Visual and exploratory investigations can depend more on human judgment than scripted examples. Use Gherkin where the conversation about observable behavior makes the added maintenance worthwhile.
Conclusion
Gherkin works best when a team uses it to settle what a feature should do. Start with one business rule, write a concrete example, and check that everyone interprets it the same way. Automate the example when the repeatable feedback is worth the work of maintaining its step definitions.