Gherkin Syntax Mastery

All keywords, Background, Tags, Rule, doc strings

The Complete Gherkin Keywords

Gherkin has a small but powerful set of keywords. Here’s every single one with its purpose:

KeywordPurposeRequired?
FeatureNames and describes the feature under testYes (one per file)
ScenarioDefines a single test caseYes (at least one)
GivenPrecondition — sets up the contextNo, but recommended
WhenAction — the event being testedNo, but recommended
ThenOutcome — the expected resultNo, but recommended
AndContinues the previous Given/When/ThenNo
ButNegative continuation (reads better for exclusions)No
BackgroundShared steps that run before every scenarioNo
Scenario OutlineTemplate for data-driven scenariosNo
ExamplesData table for Scenario OutlineRequired with Outline
RuleGroups related scenarios under a business ruleNo (Cucumber 6+)
@tagLabels for filtering and organizingNo
#Comment lineNo
"""Doc string (multi-line text)No
``Data table row delimiter

Feature & Scenario

Feature Block

Every .feature file starts with exactly one Feature: keyword:

Feature: Shopping Cart Management
  As an online shopper
  I want to manage items in my cart
  So that I can purchase what I need

The description lines (As a / I want / So that) are optional free text. Cucumber ignores them — they’re purely for human readers. You can write any description you like:

Feature: Password Reset
  This feature covers all password reset scenarios including
  email verification, security questions, and token expiration.
  Priority: High | Sprint: 24.3 | Owner: QA Team

Scenario Block

Each Scenario represents one specific test case with a clear name that describes what’s being tested:

Feature: User Registration

  Scenario: Successful registration with all required fields
    Given I am on the registration page
    When I fill in the registration form with valid data
    And I accept the terms and conditions
    And I click the register button
    Then I should see a confirmation message
    And I should receive a verification email

  Scenario: Registration fails without email
    Given I am on the registration page
    When I fill in the form without an email
    And I click the register button
    Then I should see an error "Email is required"

Background — Shared Setup

When every scenario in a feature file starts with the same steps, use Background to avoid repetition:

Without Background (Repetitive)

Feature: Shopping Cart

  Scenario: Add item to cart
    Given I am logged in as a customer
    And I am on the products page
    When I add "Laptop" to the cart
    Then the cart should contain 1 item

  Scenario: Remove item from cart
    Given I am logged in as a customer
    And I am on the products page
    When I add "Laptop" to the cart
    And I remove "Laptop" from the cart
    Then the cart should be empty

With Background (Clean)

Feature: Shopping Cart

  Background:
    Given I am logged in as a customer
    And I am on the products page

  Scenario: Add item to cart
    When I add "Laptop" to the cart
    Then the cart should contain 1 item

  Scenario: Remove item from cart
    When I add "Laptop" to the cart
    And I remove "Laptop" from the cart
    Then the cart should be empty

Tags — Organize and Filter

Tags let you categorize, filter, and selectively run scenarios. They start with @ and can be placed on Features, Scenarios, Scenario Outlines, and Examples tables.

Applying Tags

@regression
Feature: User Login

  @smoke @priority-high
  Scenario: Successful login
    Given I am on the login page
    When I login with valid credentials
    Then I should see the dashboard

  @negative @priority-medium
  Scenario: Login with wrong password
    Given I am on the login page
    When I login with invalid password
    Then I should see an error message

  @wip
  Scenario: Login with expired account
    Given I have an expired account
    When I try to login
    Then I should see "Account expired" message

Tag Inheritance

Tags on the Feature line are inherited by all scenarios in that file. In the example above, every scenario automatically has @regression.

Running with Tags

// In TestRunner
@CucumberOptions(
    features = "src/test/resources/features",
    glue = "com.gyancode.cucumber.stepdefinitions",
    tags = "@smoke and not @wip"
)
# From command line
mvn test -Dcucumber.filter.tags="@smoke"
mvn test -Dcucumber.filter.tags="@smoke and @login"
mvn test -Dcucumber.filter.tags="@smoke or @regression"
mvn test -Dcucumber.filter.tags="not @wip"
mvn test -Dcucumber.filter.tags="(@smoke or @regression) and not @skip"

Common Tag Strategies

TagPurpose
@smokeCritical path tests — run on every build
@regressionFull regression suite — run nightly
@wipWork in progress — skip in CI
@negativeNegative/error scenarios
@apiAPI-only tests (no UI)
@slowLong-running tests
@JIRA-1234Linked to a specific ticket
@sprint-24Tied to a development sprint

Rule — Group by Business Rule

The Rule keyword (Cucumber 6+) groups scenarios that verify the same business rule. It adds a semantic layer between Feature and Scenario:

Feature: Account Withdrawal

  Rule: Withdrawal is allowed when account has sufficient funds

    Scenario: Withdraw within balance
      Given my account balance is 500
      When I withdraw 200
      Then my new balance should be 300

    Scenario: Withdraw exact balance
      Given my account balance is 500
      When I withdraw 500
      Then my new balance should be 0

  Rule: Withdrawal is denied when funds are insufficient

    Scenario: Withdraw more than balance
      Given my account balance is 500
      When I try to withdraw 600
      Then I should see "Insufficient funds"
      And my balance should remain 500

  Rule: Daily withdrawal limit is enforced

    Scenario: Exceed daily withdrawal limit
      Given my account balance is 10000
      And the daily limit is 2000
      When I try to withdraw 3000
      Then I should see "Exceeds daily limit"

Doc Strings — Multi-line Text

When a step needs a large block of text (JSON body, email content, error message), use doc strings with triple quotes:

Scenario: Create user via API
  Given the API is available
  When I send a POST request to "/api/users" with body:
    """json
    {
      "firstName": "John",
      "lastName": "Doe",
      "email": "john@example.com",
      "role": "admin"
    }
    """
  Then the response status should be 201

In the step definition, the doc string is received as a String parameter:

@When("I send a POST request to {string} with body:")
public void sendPostRequest(String endpoint, String body) {
    // 'body' contains the entire JSON block
    response = given()
        .contentType(ContentType.JSON)
        .body(body)
        .post(endpoint);
}

Doc Strings with Content Type

The content type hint after """ (like """json or """xml) is optional and is for readability. Cucumber passes the raw text regardless.

Scenario: Verify email content
  When the system sends a welcome email
  Then the email body should contain:
    """
    Dear John,

    Welcome to our platform! Your account has been
    successfully created.

    Best regards,
    The Team
    """

Data Tables — Structured Data in Steps

Data tables pass structured data to a step. They’re defined with pipe characters (|) right after a step:

Scenario: Register a new user
  When I fill in the registration form:
    | field     | value             |
    | firstName | John              |
    | lastName  | Doe               |
    | email     | john@example.com  |
    | password  | SecurePass123     |
  Then the registration should be successful

Different Table Shapes

Key-Value Pairs (2 columns)

When I configure the settings:
  | timeout    | 30      |
  | retries    | 3       |
  | headless   | true    |

Single Column (List)

Then the following items should be in the cart:
  | Laptop  |
  | Mouse   |
  | Keyboard|

Multiple Rows with Headers

When I create the following users:
  | username | email            | role   |
  | john     | john@test.com    | admin  |
  | jane     | jane@test.com    | user   |
  | bob      | bob@test.com     | viewer |

Comments and Descriptions

Comments

Lines starting with # are comments and are ignored by Cucumber:

# This feature covers the payment processing module
# Last updated: Feb 2026 by QA team

Feature: Payment Processing

  # Positive scenarios
  Scenario: Successful credit card payment
    Given I have items in my cart
    # TODO: Add step for applying discount code
    When I pay with a valid credit card
    Then the payment should be processed

Descriptions

Free-form text after Feature, Scenario, Rule, or Background names:

Feature: Inventory Management
  Manages product stock levels, reorder alerts,
  and warehouse allocation.

  Scenario: Low stock alert triggers notification
  When a product drops below the reorder threshold,
  the system should notify the warehouse manager.
    Given "Widget A" has a reorder threshold of 10
    And the current stock of "Widget A" is 15
    When 6 units of "Widget A" are sold
    Then a low stock alert should be sent

Scenario Outline — A Quick Preview

When you want to run the same scenario with multiple data sets, use Scenario Outline with Examples:

Feature: Login Validation

  Scenario Outline: Login with different credentials
    Given I am on the login page
    When I enter username "<username>"
    And I enter password "<password>"
    And I click login
    Then I should see "<result>"

    Examples:
      | username    | password    | result              |
      | validuser   | validpass   | Welcome             |
      | invaliduser | validpass   | Invalid credentials |
      | validuser   | wrongpass   | Invalid credentials |
      |             | validpass   | Username required   |
      | validuser   |             | Password required   |

This generates 5 separate scenarios, one for each row in the Examples table. The angle brackets (<username>) are placeholders that get replaced with values from each row.

Feature File Organization

src/test/resources/features/
├── authentication/
│   ├── login.feature
│   ├── logout.feature
│   ├── password_reset.feature
│   └── registration.feature
├── shopping/
│   ├── cart.feature
│   ├── checkout.feature
│   ├── product_search.feature
│   └── wishlist.feature
├── user_management/
│   ├── profile.feature
│   ├── settings.feature
│   └── notifications.feature
└── api/
    ├── user_api.feature
    ├── product_api.feature
    └── order_api.feature

Feature File Naming Conventions

ConventionExample
Use snake_case or kebab-casepassword_reset.feature
Name by feature, not by pagecheckout.feature not checkout_page.feature
One feature per fileDon’t mix login and registration in one file
Group by business domainshopping/, authentication/
Keep scenarios under 10 per fileSplit large features into sub-features

A Well-Organized Feature File

@authentication @regression
Feature: User Login
  Validates the login functionality for registered users
  including successful login, failed attempts, and account lockout.

  Background:
    Given the application is running
    And I am on the login page

  @smoke @priority-high
  Scenario: Successful login with valid credentials
    When I login with valid credentials
    Then I should see the dashboard
    And the last login time should be updated

  @negative
  Scenario: Login fails with incorrect password
    When I login with incorrect password
    Then I should see "Invalid credentials"
    But I should remain on the login page

  @negative @security
  Scenario: Account locks after 5 failed attempts
    When I attempt login with wrong password 5 times
    Then my account should be locked
    And I should see "Account locked. Try again in 30 minutes."

Summary