BDD scenarios
Behavior-driven development (BDD) scenarios earn their keep only when a
product owner reads one and agrees it describes the intended behavior. Padded
with UI clicks or written in code-speak, they become slow tests that nobody
outside engineering trusts. The whole discipline is keeping each scenario in
the language of the business, not the implementation.
Method
- One scenario, one rule. A scenario names a single behavior:
Applying an expired coupon leaves the price unchanged. If the title
needs "and" to be honest, split it. Twelve tight scenarios read better
than three that each test four things.
- Given sets state, When is one action, Then is the observable result.
Given is prior facts (
Given a cart totaling $80), When is the single
trigger under test (When the customer applies coupon SAVE10), Then is
what a user or the system can see (Then the total is $72). Never put an
action in Given or a second When before the Then.
- Speak the domain, not the DOM. Write
When the customer submits the order, not When I click #submit-btn. Selectors and keystrokes belong in
the step definitions, hidden from the reader. A scenario tied to markup
breaks on a redesign that changed no behavior.
- Push the value matrix into Scenario Outline. One outline with an
Examples table covers
SAVE10, SAVE20, and an expired code in three
rows instead of three near-identical scenarios. Keep each row a distinct
rule, not just a distinct number.
- Keep Background to shared facts only. Background runs before every
scenario in the file, so it holds setup common to all of them and nothing
scenario-specific. If a Given appears in every scenario, promote it; if it
appears in two, leave it inline.
- Bind steps to intent in the step layer. With Cucumber, Behave,
pytest-bdd, or SpecFlow, one step phrase maps to one function. Reuse
phrases so the vocabulary stays small and the glue code stays shared.
Litmus tests
- Can a non-engineer read the
.feature file aloud and say whether it
matches the intended rule?
- Does every Then assert something a user or downstream system observes,
never an internal call or private field?
- If the UI were rebuilt with new markup, would the scenarios survive
untouched while only step definitions changed?
Boundaries
BDD is for behavior stakeholders care about, not for exhaustive edge cases:
push the empty, boundary, and malformed-input matrix down to unit tests where
it stays fast and cheap. Follow the team's existing feature-file layout and
tag scheme over the structure shown here.
1---2name: bdd-scenarios3description: Write given-when-then scenarios in domain language so stakeholders can read and confirm the behavior each test protects. Use when drafting acceptance criteria or Gherkin features for a user-facing rule.4---56# BDD scenarios78Behavior-driven development (BDD) scenarios earn their keep only when a9product owner reads one and agrees it describes the intended behavior. Padded10with UI clicks or written in code-speak, they become slow tests that nobody11outside engineering trusts. The whole discipline is keeping each scenario in12the language of the business, not the implementation.1314## Method15161. **One scenario, one rule.** A scenario names a single behavior:17 `Applying an expired coupon leaves the price unchanged`. If the title18 needs "and" to be honest, split it. Twelve tight scenarios read better19 than three that each test four things.202. **Given sets state, When is one action, Then is the observable result.**21 Given is prior facts (`Given a cart totaling $80`), When is the single22 trigger under test (`When the customer applies coupon SAVE10`), Then is23 what a user or the system can see (`Then the total is $72`). Never put an24 action in Given or a second When before the Then.253. **Speak the domain, not the DOM.** Write `When the customer submits the26 order`, not `When I click #submit-btn`. Selectors and keystrokes belong in27 the step definitions, hidden from the reader. A scenario tied to markup28 breaks on a redesign that changed no behavior.294. **Push the value matrix into Scenario Outline.** One outline with an30 Examples table covers `SAVE10`, `SAVE20`, and an expired code in three31 rows instead of three near-identical scenarios. Keep each row a distinct32 rule, not just a distinct number.335. **Keep Background to shared facts only.** Background runs before every34 scenario in the file, so it holds setup common to all of them and nothing35 scenario-specific. If a Given appears in every scenario, promote it; if it36 appears in two, leave it inline.376. **Bind steps to intent in the step layer.** With Cucumber, Behave,38 pytest-bdd, or SpecFlow, one step phrase maps to one function. Reuse39 phrases so the vocabulary stays small and the glue code stays shared.4041## Litmus tests4243- Can a non-engineer read the `.feature` file aloud and say whether it44 matches the intended rule?45- Does every Then assert something a user or downstream system observes,46 never an internal call or private field?47- If the UI were rebuilt with new markup, would the scenarios survive48 untouched while only step definitions changed?4950## Boundaries5152BDD is for behavior stakeholders care about, not for exhaustive edge cases:53push the empty, boundary, and malformed-input matrix down to unit tests where54it stays fast and cheap. Follow the team's existing feature-file layout and55tag scheme over the structure shown here.