bdd-practices.md

  1# BDD practices
  2
  3## Contents
  4
  5- [Discovery](#discovery)
  6- [Formulation](#formulation)
  7- [Automation](#automation)
  8- [Common myths](#common-myths)
  9
 10## Discovery
 11
 12Discovery is the most important practice. Without it, formulating scenarios is a waste of time.
 13
 14The 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.
 15
 16### Example mapping
 17
 18A lightweight discovery technique using four types of information:
 19
 20- **Story** — the capability under discussion
 21- **Rules** — constraints or acceptance criteria that summarise groups of examples
 22- **Examples** — concrete illustrations of how a rule plays out
 23- **Questions** — unknowns that can't be answered yet
 24
 25Work 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.
 26
 27### What makes a good example
 28
 29- **Concrete**, not abstract — use specific names, values, paths
 30- **Technology-agnostic** — describe what happens, not how the system does it
 31- **Focused** — each example illustrates one rule or edge case
 32- **Minimal** — include only details that affect the outcome
 33
 34### When working solo or with an LLM
 35
 36Discovery still applies. Before writing any scenario:
 37
 381. Read the relevant spec or requirement
 392. List the rules (constraints, acceptance criteria)
 403. For each rule, identify 2–3 concrete examples including at least one edge case
 414. Note any questions or assumptions
 42
 43## Formulation
 44
 45Formulation turns discovered examples into Gherkin feature files that are both human-readable specifications and executable tests.
 46
 47### Priorities
 48
 491. Readability — a non-developer should confirm "yes, that's what we want"
 502. Declarative style — describe _what_, not _how_
 513. Domain language — use the same terms the team uses when talking about the problem, all the way down into step definitions and code
 524. Reusability — steps should be composable across scenarios and features
 53
 54### The declarative test
 55
 56Ask: "will this wording need to change if the implementation does?" If yes, rewrite it. Scenarios should survive refactors.
 57
 58```gherkin
 59# Declarative — survives implementation changes
 60When Bob logs in with valid credentials
 61Then he sees his dashboard
 62
 63# Imperative — breaks when UI changes
 64When I enter "bob" in the username field
 65And I enter "secret" in the password field
 66And I click the login button
 67Then I see the text "Welcome, Bob"
 68```
 69
 70### Using Rule
 71
 72`Rule` groups scenarios under a single business rule. It provides structure without adding verbosity:
 73
 74```gherkin
 75Feature: Worktree deletion
 76
 77  Rule: Clean worktrees can be deleted without force
 78
 79    Scenario: Delete a clean worktree
 80      ...
 81
 82    Scenario: Delete rejects dirty worktree without force
 83      ...
 84
 85  Rule: Force overrides the dirty check
 86
 87    Scenario: Force-delete a dirty worktree
 88      ...
 89
 90  Rule: The primary worktree is never deletable
 91
 92    Scenario: Reject deletion of primary worktree
 93      ...
 94```
 95
 96### Using Background
 97
 98Move 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.
 99
100### Using Scenario Outline
101
102Collapse scenarios that differ only in values:
103
104```gherkin
105Scenario Outline: URL parsing
106  Given the remote URL "<url>"
107  When the URL is parsed
108  Then the host is "<host>" and the project is "<project>"
109
110  Examples:
111    | url                                    | host           | project |
112    | git@github.com:user/repo.git           | github.com     | repo    |
113    | https://git.sr.ht/~user/repo           | git.sr.ht      | repo    |
114    | ssh://git@github.com/user/repo.git     | github.com     | repo    |
115```
116
117## Automation
118
119Automation connects formulated scenarios to the system as tests. The scenario drives the implementation, not the other way around.
120
121### Automating scenarios _after_ implementation is not BDD
122
123It'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.
124
125### Step definitions are glue
126
127Steps 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.
128
129## Common myths
130
131- **Using gocuke means you're doing BDD** — BDD is the three practices, not the tool. gocuke is automation infrastructure.
132- **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.
133- **Discovery doesn't need a conversation** — even when working solo, the structured thinking of identifying rules, examples, and questions counts. Don't skip it.
134- **Scenarios are tests** — they are, but they're also living documentation and specifications. Write them for a reader, not just a test runner.