
Gherkin Syntax: Keywords, Examples and Cheat Sheet
Gherkin is the plain-text language Cucumber, SpecFlow/Reqnroll, Behave and other BDD tools read from .feature files. A file holds one Feature, which contains scenarios (Scenario or its synonym Example), and each scenario is a list of steps that start with Given, When, Then, And or But. Below is every keyword in the official Gherkin reference, with a working example of each and the mistakes that make feature files hard to maintain.
Gherkin syntax cheat sheet
| Keyword | Colon? | What it does |
|---|---|---|
Feature: |
Yes | One per file, must be the first keyword. Names the feature; text below it is a free-form description |
Rule: |
Yes | Groups the scenarios that illustrate one business rule (Gherkin 6+) |
Scenario: / Example: |
Yes | One concrete example of behavior, made of steps |
Given |
No | Puts the system in a known state |
When |
No | The action or event |
Then |
No | The observable outcome |
And, But |
No | Continue the previous step type, for readability |
* |
No | Replaces any step keyword (handy for list-like steps) |
Background: |
Yes | Steps that run before every scenario in the Feature or Rule |
Scenario Outline: / Scenario Template: |
Yes | A scenario template run once per row of an Examples table |
Examples: / Scenarios: |
Yes | The data table for an outline |
""" or three backticks |
No | Doc String: a multi-line text argument for a step |
| |
No | Data Table: a table argument for a step |
@tag |
No | Labels a Feature, Rule, Scenario, Outline or Examples block |
# |
No | Comment (must start the line) |
The colon matters. The reference warns that if you put a colon after a keyword that shouldn't have one, your tests will be ignored.
A complete feature file
# language: en
@checkout
Feature: Discount codes
Customers can enter one discount code at checkout.
Codes are case-insensitive.
Background:
Given the catalog contains "Mechanical keyboard" priced at $120.00
And I have "Mechanical keyboard" in my cart
Rule: A valid code reduces the order total
Example: Percentage code
When I apply the code "SAVE10"
Then the order total is $108.00
Example: Codes are case-insensitive
When I apply the code "save10"
Then the order total is $108.00
Rule: Only one code per order
@regression
Example: A second code replaces the first
Given I have applied the code "SAVE10"
When I apply the code "FREESHIP"
Then only the code "FREESHIP" is active
But the order total is $120.00
What's happening:
# language: enis optional (English is the default). It must be the first line if used.@checkouton the Feature is inherited by every scenario in the file.Backgroundruns before eachExample, in both rules.- Each
Rulegroups the examples that prove one business rule.
Feature and descriptions
A .feature file may contain only one Feature. Any text under Feature:, Rule:, Scenario:, Background: or Scenario Outline: that doesn't start with a keyword is a description. Cucumber ignores it at runtime, but it shows up in reports, and the official HTML formatter renders Markdown in it. Use it for the "why": the user story, links to tickets, edge cases you deliberately left out.
Steps: Given, When, Then, And, But
The reference gives each step type a job:
- Given sets up the initial context. It should describe state, not user interaction ("Given I am logged in as an admin", not "Given I click Login").
- When is the event or action under test. Most scenarios have exactly one.
- Then checks an outcome the user or an external system could observe. Avoid asserting on internal state such as database rows.
- And and But just continue whatever came before.
Butreads better for negatives.
One detail that surprises people: keywords are ignored when steps are matched to step definitions. Given there is 1 item and Then there is 1 item match the same definition, and Cucumber treats two definitions for that text as a duplicate. The keyword is for humans.
The asterisk replaces any keyword when steps read like a list:
Scenario: Packing for a trip
Given I am out shopping
* I have eggs
* I have milk
* I have butter
When I check my list
Then I don't need anything
The reference suggests 3 to 5 steps per scenario. Longer scenarios usually mean the steps describe clicks instead of behavior.
Background
Background holds steps that repeat at the start of every scenario. Rules from the reference:
- Only one
BackgroundperFeatureor perRule. - It goes before the first scenario at the same indentation level.
- It runs before each scenario, after any
Beforehooks.
Keep it short (the docs suggest four lines or fewer). If a reader has to scroll up to understand a scenario, move the setup into a clearly named Given or a hook.
Scenario Outline and Examples
When the same scenario runs with different data, use a Scenario Outline (synonym Scenario Template) with <placeholders> and an Examples table. It runs once per data row, not counting the header.
Scenario Outline: Shipping cost by country
Given my cart total is <total>
When I ship to "<country>"
Then shipping costs <shipping>
@domestic
Examples: Domestic
| total | country | shipping |
| $20.00 | US | $5.00 |
| $80.00 | US | $0.00 |
@international
Examples: International
| total | country | shipping |
| $20.00 | DE | $15.00 |
An outline needs at least one Examples block, and each block can have its own name and tags, so you can run only @domestic rows. Placeholders also work inside doc strings and data tables. For step-definition code in cucumber-js and Cucumber-JVM, see our guide to Scenario Outline tips and examples.
Step arguments: doc strings and data tables
Doc strings
A doc string passes a block of text to the step, as the step definition's last argument. Wrap it in """ (or three backticks), each on its own line. You can put a content type after the opening delimiter:
Scenario: Creating an order through the API
When I POST to "/orders" with:
"""json
{
"sku": "KB-001",
"quantity": 2
}
"""
Then the response status is 201
Indentation inside the doc string is relative to the opening """, so extra indentation is kept. The reference notes that many tools and editors don't support the backtick form or content types yet, so """ is the safer choice.
Data tables
A data table passes rows to the step definition, again as the last argument:
Given these users exist:
| name | email | role |
| Alice | alice@example.com | admin |
| Bob | bob@example.com | user |
Inside a cell, escape a newline as \n, a pipe as \|, and a backslash as \\. Each Cucumber implementation has a Data Table API to turn rows into maps or objects.
Note the difference: an Examples table runs the whole scenario once per row; a data table is one argument to one step.
Tags
Tags start with @, are separated by spaces, and can go above Feature, Rule, Scenario, Scenario Outline and Examples, but not above Background or individual steps (Cucumber docs). Children inherit their parents' tags.
Select scenarios with a tag expression using and, or, not and parentheses:
# cucumber-js
npx cucumber-js --tags "@smoke and not @slow"
# Cucumber-JVM with Maven
mvn test -Dcucumber.filter.tags="(@smoke or @ui) and not @wip"
Comments and languages
Comments start with # at the beginning of a line (leading spaces are allowed). There are no block comments, and a # in the middle of a step is part of the step text.
Gherkin is translated into more than 70 spoken languages. Put # language: fr (or de, es, ja...) on the first line, and the keywords change: Fonctionnalité, Scénario, Soit, Quand, Alors.
Gherkin anti-patterns to avoid
Imperative steps. Describing clicks couples the spec to the UI:
# Brittle
When I click "#email"
And I type "alice@example.com"
And I click the "Sign in" button
# Better: says what, not how
When Alice signs in
Several Whens in one scenario. Usually two behaviors; split them.
Then checking internals. "Then the users table has 1 row" tests the implementation. Assert what the user sees or what the API returns.
Giant Backgrounds and Examples tables. Ten rows that all exercise the same rule hide the one row that matters. Keep examples that each show something different.
Gherkin without conversations. Gherkin is meant to capture examples the team agreed on. If only testers write it after the fact, a plain test framework is cheaper. For folder layout, naming and review habits, see 10 best practices for organizing BDD features and scenarios.
Writing acceptance criteria in Gherkin
Gherkin works well for user-story acceptance criteria because each scenario is a testable example. A practical pattern: write the story as the Feature description, one Rule per acceptance criterion, and one or two Examples under each rule. Product owners can review the file, and the same file runs in CI. Tooling for running feature files and other test types is in DevHunt's testing tools directory.
FAQ
What is Gherkin syntax used for?
It is used to write executable specifications for behavior-driven development. Tools such as Cucumber (JavaScript, Java, Ruby), Reqnroll (.NET) and Behave (Python) parse .feature files and match each step to code in a step definition.
What is the difference between Scenario and Example?
None. Example is a synonym for Scenario, and Scenario Template is a synonym for Scenario Outline. Example reads well under a Rule.
Can a feature file have more than one Feature or Background?
No to the first: one Feature per file. A Background is allowed once per Feature and once per Rule.
What is the difference between Examples and a data table?
Examples belongs to a Scenario Outline and runs the scenario once per row. A data table belongs to a single step and is passed to its step definition as an argument.
Does the step keyword matter when matching step definitions?
No. Cucumber ignores Given/When/Then when matching, so the same text under two keywords matches the same step definition.