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
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.<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.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.