Published Sep 16, 2025 ⦁ Updated Oct 11, 2026 ⦁ 9 min read
Gherkin Syntax: Keywords, Examples and Cheat Sheet

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: en is optional (English is the default). It must be the first line if used.
  • @checkout on the Feature is inherited by every scenario in the file.
  • Background runs before each Example, in both rules.
  • Each Rule groups 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. But reads 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 Background per Feature or per Rule.
  • It goes before the first scenario at the same indentation level.
  • It runs before each scenario, after any Before hooks.

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.