Gherkin Syntax — Writing Feature Files with Given, When, Then

Gherkin is the structured, plain-language syntax that BDD scenarios are written in. Every scenario follows the Given-When-Then pattern: Given a precondition, When an action occurs, Then an expected outcome should happen. Gherkin files use the .feature extension and are organised by feature, with each feature containing multiple scenarios that describe different behaviours.

Gherkin Syntax — The Complete Reference

Gherkin has a small set of keywords that express business requirements as executable specifications.

# ── Basic scenario ──

Feature: User Login
  As a registered user
  I want to log in to my account
  So that I can access my personalised dashboard

  Scenario: Successful login with valid credentials
    Given I am on the login page
    When I enter username "standard_user" and password "secret_sauce"
    And I click the login button
    Then I should see the inventory page
    And I should see 6 products displayed


  Scenario: Failed login shows error message
    Given I am on the login page
    When I enter username "invalid_user" and password "wrong_pass"
    And I click the login button
    Then I should see an error message containing "do not match"


  # ── Background — shared setup for all scenarios ──

  Background:
    Given I am on the login page

  Scenario: Locked user sees lockout message
    When I enter username "locked_out_user" and password "secret_sauce"
    And I click the login button
    Then I should see an error message containing "locked out"


  # ── Scenario Outline — data-driven scenarios ──

  Scenario Outline: Login with various user types
    When I enter username "<username>" and password "<password>"
    And I click the login button
    Then I should see "<expected_result>"

    Examples:
      | username        | password     | expected_result          |
      | standard_user   | secret_sauce | the inventory page       |
      | locked_out_user | secret_sauce | error: locked out        |
      | problem_user    | secret_sauce | the inventory page       |
      | invalid_user    | wrong_pass   | error: do not match      |


  # ── Data Tables — structured data in steps ──

  Scenario: Add multiple products to cart
    Given I am logged in as "standard_user"
    When I add the following products to the cart:
      | Product Name       |
      | Sauce Labs Backpack|
      | Sauce Labs Onesie  |
      | Sauce Labs Bolt T-Shirt |
    Then the cart should contain 3 items


  # ── Tags — organise and filter scenarios ──

  @smoke @login
  Scenario: Quick login verification
    Given I am on the login page
    When I enter valid credentials
    Then I should be logged in

  @regression @checkout
  Scenario: Complete purchase flow
    Given I am logged in as "standard_user"
    When I add a product and complete checkout
    Then I should see the order confirmation
Note: The Given-When-Then pattern maps directly to the Arrange-Act-Assert pattern used in traditional testing: Given sets up the precondition (Arrange), When performs the action (Act), and Then verifies the outcome (Assert). The And keyword continues the previous step type — And I click the login button after a When step is treated as another When. This mapping makes Gherkin scenarios structurally identical to well-written test methods, just expressed in business language.
Tip: Use Scenario Outline with an Examples table for data-driven scenarios. The runner executes the scenario once per row in the table, substituting <username>, <password>, and <expected_result> with the row’s values. This is the Gherkin equivalent of @pytest.mark.parametrize — one scenario template, multiple data sets, individual results per row.
Warning: Write scenarios in business language, not implementation language. When I click the element with ID "login-btn" is implementation detail that belongs in step definitions, not in Gherkin. When I click the login button is business language that stakeholders can read and review. If your Gherkin reads like code, it has lost its primary value: being a communication tool between technical and non-technical team members.

Common Mistakes

Mistake 1 — Writing imperative scenarios instead of declarative ones

❌ Wrong: When I type "alice" into the username field / And I type "pass" into the password field / And I click the submit button — step-by-step UI instructions.

✅ Correct: When I log in with valid credentials — describes the business action. Implementation details belong in step definitions.

Mistake 2 — Writing scenarios that are too long (more than 5-7 steps)

❌ Wrong: A 15-step scenario that covers login, browse, add to cart, checkout, payment, and confirmation — testing too many behaviours in one scenario.

✅ Correct: Each scenario focuses on one behaviour. Split the 15-step scenario into 4 focused scenarios: login, add to cart, checkout, and payment confirmation.

🧠 Test Yourself

What Gherkin keyword creates a data-driven scenario that runs once per row in an Examples table?