BDD practices
Contents
Discovery
Discovery is the most important practice. Without it, formulating scenarios is a waste of time.
The goal is shared understanding of the behaviour to build. Use structured conversations (discovery workshops, example mapping) to explore concrete examples from the user's perspective.
Example mapping
A lightweight discovery technique using four types of information:
- Story — the capability under discussion
- Rules — constraints or acceptance criteria that summarise groups of examples
- Examples — concrete illustrations of how a rule plays out
- Questions — unknowns that can't be answered yet
Work through rules one at a time, attaching examples that illustrate each. Capture questions to research later rather than guessing. If there are too many rules or too many questions, the story is too large or too vague — break it down.
What makes a good example
- Concrete, not abstract — use specific names, values, paths
- Technology-agnostic — describe what happens, not how the system does it
- Focused — each example illustrates one rule or edge case
- Minimal — include only details that affect the outcome
When working solo or with an LLM
Discovery still applies. Before writing any scenario:
- Read the relevant spec or requirement
- List the rules (constraints, acceptance criteria)
- For each rule, identify 2–3 concrete examples including at least one edge case
- Note any questions or assumptions
Formulation
Formulation turns discovered examples into Gherkin feature files that are both human-readable specifications and executable tests.
Priorities
- Readability — a non-developer should confirm "yes, that's what we want"
- Declarative style — describe what, not how
- Domain language — use the same terms the team uses when talking about the problem, all the way down into step definitions and code
- Reusability — steps should be composable across scenarios and features
The declarative test
Ask: "will this wording need to change if the implementation does?" If yes, rewrite it. Scenarios should survive refactors.
# Declarative — survives implementation changes
When Bob logs in with valid credentials
Then he sees his dashboard
# Imperative — breaks when UI changes
When I enter "bob" in the username field
And I enter "secret" in the password field
And I click the login button
Then I see the text "Welcome, Bob"
Using Rule
Rule groups scenarios under a single business rule. It provides structure without adding verbosity:
Feature: Worktree deletion
Rule: Clean worktrees can be deleted without force
Scenario: Delete a clean worktree
...
Scenario: Delete rejects dirty worktree without force
...
Rule: Force overrides the dirty check
Scenario: Force-delete a dirty worktree
...
Rule: The primary worktree is never deletable
Scenario: Reject deletion of primary worktree
...
Using Background
Move shared preconditions to Background when they appear in every scenario under a Feature or Rule. Keep it short (≤ 4 lines). If it scrolls off screen, the reader loses context.
Using Scenario Outline
Collapse scenarios that differ only in values:
Scenario Outline: URL parsing
Given the remote URL "<url>"
When the URL is parsed
Then the host is "<host>" and the project is "<project>"
Examples:
| url | host | project |
| git@github.com:user/repo.git | github.com | repo |
| https://git.sr.ht/~user/repo | git.sr.ht | repo |
| ssh://git@github.com/user/repo.git | github.com | repo |
Automation
Automation connects formulated scenarios to the system as tests. The scenario drives the implementation, not the other way around.
Automating scenarios after implementation is not BDD
It's a perfectly reasonable way to do test automation, but the value of BDD is that failing tests guide the implementation. Writing tests after the fact loses that feedback loop.
Step definitions are glue
Steps connect Gherkin to your system. They should be thin — call into the real code, set up fixtures, make assertions. Don't put business logic in step definitions.
Common myths
- Using gocuke means you're doing BDD — BDD is the three practices, not the tool. gocuke is automation infrastructure.
- You can pick practices in any order — Discovery → Formulation → Automation. Having conversations is more important than capturing them, which is more important than automating them.
- Discovery doesn't need a conversation — even when working solo, the structured thinking of identifying rules, examples, and questions counts. Don't skip it.
- Scenarios are tests — they are, but they're also living documentation and specifications. Write them for a reader, not just a test runner.