Gherkin to Code
The Gherkin-to-code workflow starts with a failing scenario, implements minimal step definitions, then builds application code until the scenario passes. This is outside-in development with executable acceptance criteria.
Recipe
1. Write scenario (fails - no steps)
2. Implement step stubs (fails - NotImplementedError)
3. Build application code (scenario passes)
4. Refactor steps and application together
When to reach for this:
- New feature with clear acceptance criteria
- Team practices BDD as a design discipline
- Stakeholders review scenarios before implementation
Working Example
# features/discount.feature
Feature: Volume discount
Scenario: 10% discount for orders over 1000
Given a customer with a cart total of 1500.00
When the discount is calculated
Then the discount amount is 150.00
And the final total is 1350.00# Step 1: failing steps
from pytest_bdd import scenarios, given, when, then, parsers
scenarios("../discount.feature")
_cart = {}
@given(parsers.parse("a customer with a cart total of {total:f}"))
def cart_total(total):
_cart["total"] = total
@when("the discount is calculated")
def calculate():
from myapp.discount import apply_volume_discount
_cart["result"] = apply_volume_discount(_cart["total"])
@then(parsers.parse("the discount amount is {amount:f}"))
def check_discount(amount):
assert _cart["result"]["discount"] == amount
@then(parsers.parse("the final total is {total:f}"))
def check_final(total):
assert _cart["result"]["final"] == total# Step 2: minimal application code
def apply_volume_discount(total: float) -> dict[str, float]:
if total > 1000:
discount = total * 0.10
else:
discount = 0.0
return {"discount": discount, "final": total - discount}What this demonstrates:
- Scenario drives what to build
- Steps are thin glue over
apply_volume_discount - Application code is the smallest implementation to pass
- Refactor after green
Deep Dive
Outside-In Flow
Scenario (acceptance)
-> Step definitions (glue)
-> Service function (domain)
-> Unit tests (edge cases)
When to Add Unit Tests
- After scenario passes, add pytest unit tests for edge cases (0, 1000 boundary, negative)
- Scenarios cover happy paths; unit tests cover boundaries and errors
Gotchas
- Implementing everything in steps - untestable monolith in step file. Fix: extract to
myapp/modules immediately. - Writing all scenarios upfront - waterfall BDD. Fix: one scenario per story; iterate.
- Skipping the failing step phase - green without verification. Fix: run scenario, confirm it fails for the right reason.
- Scenario too detailed - "Given database row 42 exists". Fix: domain language: "Given a premium customer."
- No unit tests after BDD - gaps at boundaries. Fix: BDD + pytest unit tests complement each other.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| TDD with pytest | Developer-only design | Stakeholder-readable specs needed |
| Spike then scenario | Unclear requirements | Requirements are clear |
| Example mapping | Workshop output | Already writing Gherkin |
FAQs
Red-green-refactor with BDD?
Yes. Red: scenario fails. Green: minimal code passes. Refactor: clean steps and application.
Who writes scenarios?
Product + dev together. Developers implement steps and application code.
How many scenarios per story?
1-3 acceptance scenarios per user story. Edge cases go to unit tests.
Can I generate step stubs?
Some IDE plugins scaffold steps from feature files. Manual implementation is fine for small suites.
What if the scenario is wrong?
Fix the scenario first. Scenarios are the spec - code follows.
How do I handle UI steps?
Use page objects behind step definitions. Gherkin stays UI-agnostic.
When is the feature done?
All scenarios green, unit tests for edge cases, stakeholders sign off on feature file.
How do I avoid step explosion?
Reuse generic steps with parameters. Limit feature-specific steps to domain language.
Should I commit failing scenarios?
Yes on a feature branch. Scenarios document intent before implementation exists.
How do I refactor safely?
Green scenarios are the safety net. Refactor application code; scenarios still pass.
Related
- Step Definitions - writing steps
- Gherkin Syntax - scenario authoring
- Assertions & Test Structure - unit test complement
- BDD Best Practices - maintenance
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+.