Gherkin Syntax
Gherkin is a plain-text language for describing software behavior. Feature files use a structured Given-When-Then format that both humans and BDD tools can execute.
Recipe
Feature: Invoice creation
As a billing clerk
I want to create invoices
So that customers receive accurate bills
Scenario: Valid invoice
Given an authenticated billing clerk
When they create an invoice for 100.00 USD
Then the invoice status is "draft"
And the invoice id is not emptyWhen to reach for this:
- Writing acceptance criteria as executable specs
- Sharing test scenarios with non-technical stakeholders
- Documenting API behavior in human-readable form
Working Example
Feature: User registration
Users must register with a valid email before accessing the system.
Background:
Given the registration API is available
Scenario: Successful registration
Given no user exists with email "ada@example.com"
When a registration request is sent with:
| email | ada@example.com |
| password | SecurePass123 |
Then the response status is 201
And a confirmation email is queued
Scenario Outline: Invalid email rejected
Given no existing user conflicts
When a registration request is sent with email "<email>"
Then the response status is 422
Examples:
| email |
| not-an-email |
| @missing.com |
| empty |What this demonstrates:
Featuredescribes the capability with user story formatBackgroundruns before every scenario in the fileScenariois a single test case with Given-When-Then stepsScenario Outline+Examplesparametrizes scenarios
Deep Dive
Keywords
| Keyword | Purpose |
|---|---|
| Feature | Groups related scenarios |
| Background | Shared setup for all scenarios |
| Scenario | Single behavior example |
| Scenario Outline | Parametrized scenario |
| Given | Preconditions (arrange) |
| When | Action (act) |
| Then | Expected outcome (assert) |
| And / But | Continuation of previous step type |
| Examples | Data table for Scenario Outline |
Data Tables
When the user submits:
| field | value |
| name | Ada |
| amount | 100 |Gotchas
- Implementation details in steps - "When I call POST /api/v2/invoices". Fix: describe behavior: "When an invoice is created."
- Too many steps per scenario - unreadable. Fix: max 5-7 steps; extract setup to Background.
- Scenario Outline with 50 examples - maintenance burden. Fix: keep examples focused on boundary cases.
- Comments as documentation - stale comments. Fix: steps should be self-describing; use tags for metadata.
- Mixing languages - Gherkin keywords must be English (or one
# language: frheader). Fix: one language per project.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| pytest docstrings | Developer-only specs | Stakeholder-readable specs needed |
| OpenAPI examples | API contract docs | User workflow behavior |
| Markdown test plans | Pre-automation exploration | Executable tests needed |
FAQs
Must I use the user story format?
No, but the Feature description should explain who benefits and why.
How many scenarios per feature file?
5-15 is manageable. Split large features into multiple files.
What are tags?
@smoke, @wip labels for filtering: pytest --tags smoke.
Can steps have multiple lines?
Yes with doc strings (""") for multiline step arguments.
Given vs When vs Then - strict?
Given = state, When = action, Then = assertion. And/But continue the previous type.
How do I write negative scenarios?
Then the response status is 403 or Then registration fails with "email taken".
Background vs Given in each scenario?
Background for shared setup across all scenarios. Scenario-specific Given for unique preconditions.
Can I use Gherkin for unit tests?
Not recommended. Gherkin is for acceptance-level behavior. Use pytest for units.
What is Rule keyword?
Gherkin 6+ groups scenarios under business rules within a Feature.
How do I handle dates in examples?
Use relative terms in steps ("today", "next Monday") resolved in step definitions.
Related
- BDD Decision Checklist - when to use BDD
- Step Definitions - wiring steps to Python
- behave / pytest-bdd Setup - project setup
- Gherkin to Code - implementing steps
Stack versions: This page was written for Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.