Case file TS2

Specification by Example

Domain-language Gherkin.

The scenario that survives a redesign talks about what the system does, not what the page looks like. Domain language survives the next CSS commit. Click-coordinates do not.

ByAdam LewisPublished3 May 2026Revised13 Oct 2026Reading11 minVersionv1.2ConfidenceHigh
§0b

Opinion

I've sat in too many sprint reviews where the demo passed acceptance and shipped a bug. The scenario said the user can register; the implementation registered the user and then dropped the welcome email without a word. Acceptance was met by a paraphrase. The fix is the same one Adzic and North have been arguing for twenty years: write the example, in the domain's words, in a form a machine can run.1 If the example doesn't cover the welcome email, the example was wrong. The conversation has to happen before the code, not after.

Most teams get the declarative-versus-imperative line wrong. When I submit the form is what the user does; When I click the third button is what the front-end happens to be wired to today. The first survives a redesign because it talks about behaviour. The second breaks the morning a designer changes the layout. Cucumber's “Writing Better Gherkin” guide makes the rule explicit2 and it is the rule almost every legacy step file ignores. Same shape as F2 Intention-Revealing Names: the domain noun wins over the implementation noun every time.

The pipeline that makes the scenario load-bearing is what stops it being theatre. P2 Spec-First Execution commands writing the AC up front. AI4 Verifiable Specs commands writing it as something a machine can grade. TS2 commands writing it declaratively in domain words. TS1 takes the resulting check and turns it into the documentation. Four tenets and four checkpoints on one artefact. Skip any one and the spec rots into prose nobody runs.

Copy a note and link

Grab this short comment and drop it into a PR comment or an LLM chat to prompt the right change.

Write the scenario in domain language. `When I submit the form` is the spec; `When I click the third button` is the implementation leaking through. Declarative not imperative. The scenario survives a redesign because it talks about what the system does, not what the DOM looks like.

/tenet/specification-by-example/TS2
Copy for paste
§0c

AI eyes only

Rule: write Gherkin in domain language. No DOM selectors, no implementation detail.

Reject: When I click "#submit-btn". Reject: scenarios that use technical IDs the product owner does not recognise. Reject: imperative click-by-click tutorials posing as scenarios.

Generate: declarative scenarios in the ubiquitous language ( When I submit my registration). Step definitions handle the mechanics. The .feature file stays domain-only.

Diagnostic: a stakeholder reads the feature file and recognises every term. If a developer has to translate, the term does not belong in the scenario.

§0d

Why?

  • Stakeholder, developer and tester share one vocabulary, Evans's ubiquitous language by another name. The scenario is the artefact all three sign.
  • The AC in the ticket is the scenario in the feature file. The story moves from analysis to development without anybody rewriting the requirement in code-flavoured prose.
  • Declarative steps survive a redesign. When I submit the form still passes after the button moves; When I click the third button breaks the morning the layout changes.
  • Slots into the four-tenet spec pipeline, P2 Spec-First Execution → AI4 Verifiable Specs → TS2 → TS1 Living Documentation. One artefact, four checkpoints, each owned by the pillar that polices it.
  • Coding agents treat the Gherkin as the canonical spec. A declarative scenario in domain words is a target the model can satisfy. An imperative one is a UI script the model reproduces one click at a time.
  • One scenario, one behaviour. The and-counting rule keeps the document diff-friendly, the failure modes attributable and the regression net legible.
  • A declarative scenario is parameterisation-ready. Pair with TS3 Parameterised Scenarios when the example becomes a table, with property-based tests when the table becomes infinite.
The receipts
Origins, quoted passages, evidence, the strongest counter-argument and the reply.
§1

Origins

Specification by Example crystallised in 2009-2011. Gojko Adzic's Bridging the Communication Gap (2009)6 set the practice; Specification by Example (2011)1 codified it as seven process patterns. Adzic chose the name deliberately over “BDD” or “ATDD”7: he wanted the term with the least negative baggage, and one that did not reduce the practice to a testing activity.

The lineage runs back through Dan North's 2006 introduction of BDD,8 where Given/When/Then was already proposed as a documentation grammar, and further back to Eric Evans's Domain-Driven Design (2003), whose ubiquitous language is the source of the “domain language” clause in the TS2 punch.9 Cucumber's “BDD History” page traces the chain explicitly.10 Liz Keogh's “What is BDD?”11 is the cleanest modern compression: examples in conversation to illustrate behaviour.

The declarative-not-imperative rule, often the part working developers most need, is Cucumber's own Writing Better Gherkin guide.2 The Three Amigos pattern (Dinwiddie, 2009)12 names the conversation half: business, development, testing in one room before the code starts. Wynne and Hellesøy's Cucumber Book13 is the reference text on putting the practice into a working test runner.

In the Prickles canon, TS2 is the third link in a four-tenet pipeline. P2 Spec-First Execution commands writing the AC up front. AI4 Verifiable Specs commands writing it as something a machine can grade. TS2 commands writing it declaratively in domain words. TS1 takes the resulting check and turns it into the documentation. The chain is the operating principle and TS2 is its testing-side phrasing rule.

§2

Quotes

Your scenarios should describe the intended behaviour of the system, not the implementation.

Cucumber Docs · Writing Better Gherkin

Using examples in conversation to illustrate behaviour.

Liz Keogh · What is BDD? (2015)

Given some initial context (the givens), When an event occurs, Then ensure some outcomes.

Dan North · Introducing BDD (2006)

Specification by Example is a set of process patterns that facilitate change in software products to ensure the right product is delivered effectively.

Gojko Adzic · Specification by Example (2011)
§3

Evidence

17 external sources, ranked by author authority. The first five are the canon; expand to see the rest, including the qualifiers and the named opposers. Each links out to its primary source.

  1. 01
    Gojko Adzic · 2011
    Codifies the practice as seven process patterns. The canonical reference. Adzic chose the term over BDD or ATDD for the cleanest description of the artefact: a specification, illustrated by examples, that the team agreed on.
  2. 02
    Gojko Adzic · 2009
    The earlier book that established the practice. Acceptance tests as agreed truth between business and developers; SBE’s grounding in the conversation half.
  3. 03
    Dan North · 2006
    The article that named BDD; Given/When/Then proposed first as a documentation grammar, second as a testing grammar. The structural ancestor of Cucumber’s Gherkin.
  4. 04
    What is BDD?Supports
    Liz Keogh · 2015
    “Using examples in conversation to illustrate behaviour.” The shortest accurate definition of the practice TS2 names.
  5. 05
    Liz Keogh · 2011
    The conversation-first idea. “BDD isn’t about the tools”. The spec is the discussion the team has, with the Gherkin file as its written record.
  1. 06
    Cucumber documentation · 2020+
    The declarative-versus-imperative rule, in Cucumber’s own words. The shortest published source for the writing-style half of TS2.
  2. 07
    BDD OverviewSupports
    Cucumber documentation · 2020+
    Cucumber’s three-practice idea: discovery, formulation, automation. SBE compressed into the loop a working team runs every sprint.
  3. 08
    Matt Wynne & Aslak Hellesøy · 2017
    The reference text on putting the practice into a working test runner. Hellesøy created Cucumber; he and Wynne, with Steve Tooke, wrote the canonical book on operating it.
  4. 09
    Eric Evans · 2003
    The concept TS2 inherits from. The team’s ubiquitous language is the source of the “domain language” clause in the punch. The scenario is its written form.
  5. 10
    George Dinwiddie · 2009
    The post where Dinwiddie uses “three amigos”, a term he borrowed from friends at Nationwide: product owner, developer and tester agree how they will know a story is done, however and whenever they meet. The conversation half SBE depends on.
  6. 11
    Martin Fowler · 2004
    Fowler says the phrase struck him at a workshop at XP/Agile Universe in 2002. Fowler’s idea: the example is what the spec turns into when it stops being abstract.
  7. 12
    Agile Alliance · 2010+
    The canonical glossary entry. Three perspectives in one room: business asks “what problem are we trying to solve?”, development asks “how might we build a solution to solve that problem?”, testing asks “what about this, what could possibly happen?”.
  8. 13
    Martin Fowler · 2013
    The clearest mainstream restatement of the Gherkin grammar as a documentation primitive. Fowler distinguishes the literary form from the test form. Both are SBE.
  9. 14
    Dan North · 2007
    The original story template plus acceptance criteria as scenarios. The cross-pillar bridge between user-story practice and SBE’s declarative scenario.
  10. 15
    Anti-PatternsQualifies
    Cucumber documentation · 2020+
    Names two failure modes: feature-coupled step definitions and conjunction steps. The boundary between SBE and step-script imitation.
  11. 16
    Hillel Wayne · 2019
    Background for Wayne’s natural-language critique. Sets up the argument that example-based specs cannot encode invariants, only their instances.
  12. 17
    J. B. Rainsberger · 2009
    Treats the integrated test SBE produces as a confidence-trick. Collaborators can drift while the scenario passes. The strongest published objection at the test-fidelity layer.

Seventeen sources, three stances. The supports above are the canon: Adzic, North, and Keogh on Specification by Example and BDD. The one qualifier, Cucumber's Anti-Patterns page, names two ways a step file goes wrong: step definitions that cannot be reused across features, and conjunction steps that combine several things into one. The opposers hold the steelman the reply has to address.

§4

Examples

Viewing: TypeScript.
Avoid

Before imperative step. Couples to the button copy "Submit".

Filerescue-steps.ts
When("I click the button with text {string}", async (label: string) => {
  await page.getByRole("button", { name: label }).click();
});
features/rescue.feature
Scenario: A volunteer records a hedgehog rescue
  Given a hedgehog has arrived at the sanctuary
  When I click the button with text "Submit"
  Then the rescue is recorded
Prefer

After declarative step. Describes the volunteer's intent.

Filerescue-steps.ts
When("I submit the hedgehog rescue form", async () => {
  await rescueForm.submit(page);
});
features/rescue.feature
Scenario: A volunteer records a hedgehog rescue
  Given a hedgehog has arrived at the sanctuary
  When I submit the hedgehog rescue form
  Then the rescue is recorded
§4b

Enforcement

Viewing: TypeScript.

Apply these rules in .gherkin-lintrc. The full enforcement across every tenet lives on the implementation page.

RuleToolCatches
no-unnamed-scenariosgherkin-lintscenarios without a name. The name is the headline; an unnamed scenario is documentation that doesn’t announce itself.
no-files-without-scenariosgherkin-lintfeature files containing only background or rule blocks. A feature without a scenario doesn’t document a behaviour.
name-lengthgherkin-lintscenario names longer than 70 chars: the threshold beyond which the headline stops working as documentation. Adjust per house style.
use-andgherkin-lintconsecutive Given/When/Then steps that should have used And for readability. The shape of the scenario is part of the spec.
playwright-bdd defineBddConfigplaywright-bddscenarios with no matching step definition. The build fails before the test runs; the spec stays honest about what is and isn’t automated.
@cucumber/cucumber --strict@cucumber/cucumberundefined or pending steps left in main. Strict mode fails the build until every step has an implementation.
.gherkin-lintrcconfiguration snippet
{
  "no-unnamed-features": "on",
  "no-unnamed-scenarios": "on",
  "no-empty-file": "on",
  "no-files-without-scenarios": "on",
  "indentation": ["on", { "Feature": 0, "Scenario": 2, "Step": 4, "Examples": 4 }],
  "use-and": "on",
  "name-length": ["on", { "Feature": 70, "Scenario": 70 }],
  "no-multiple-empty-lines": "on",
  "no-trailing-spaces": "on"
}
§4c

AI rules

File.cursor/rules/ts2-specification-by-example.mdc
---
alwaysApply: true
---

## Prickles TS2: Specification by Example

Write the scenario in the language a stakeholder uses. `When I submit the form` is the spec; `When I click the third button` is the implementation leaking through.

Declarative steps describe behaviour. Imperative steps describe interaction. The first survives a redesign. The second breaks on every CSS edit.

The Given/When/Then is the conversation, then the documentation, then the test. If it can't be read aloud at a Three Amigos meeting, rewrite it.

One scenario, one behaviour. If the scenario uses `and` more than twice, split it.

Repo layout, CI, and ESLint wiring for these paths live on /implementation, not repeated on every tenet.

§5

Counter-argument

Counter

The strongest pushback is Hillel Wayne's3: natural-language specs are ambiguous by design. A Gherkin scenario reads cleanly aloud and still means three things to three readers. The precision the test buys is precision against an example rather than against the behaviour. For systems whose correctness is genuinely bit-precise (cryptography, distributed consensus, billing) the scenario is a ladder rather than a roof. Michael Bolton sharpens the same point: he proposes calling an automated acceptance test a check. A passing check shows only that the program still works within the scope of the team's expectations.4 J. B. Rainsberger's broader objection5 is that the integrated test SBE produces gives false confidence. Collaborators can drift while the scenario passes.

§6

Counter-argument retort

Reply

Hillel Wayne's objection3 is conceded inside its scope and refused outside it. For the systems whose correctness is genuinely bit-precise (cryptographic primitives, distributed consensus, financial settlement) the right artefact is a formal spec (TLA+, Alloy, a typed invariant) and the Gherkin sits below it as the customer-facing illustration. For the systems most working developers release most days (checkout flows, registration, scheduling, content management) the ambiguity Wayne names is real and small and the upside of a stakeholder-readable spec dominates the residual ambiguity. The scenario is not the roof but the ceiling tile that covers the room you live in.

Bolton's checking-versus-testing distinction4 is the strongest sharpening. The reply concedes and adds the practices that restore the questioning view. TS3 Parameterised Scenarios generalises the example into a table, and property-based testing generalises the table into a generator that produces examples the developer hadn't imagined.14 Exploratory testing kept on the team's books as a separate activity, not pretending to be regression, completes the picture. SBE is the regression-and-documentation half. The questioning half is its companion practice, not a substitute for it.

Rainsberger's “integrated tests are a scam”5 objection runs against treating SBE’s test as the only fidelity check. The reply concedes and adds contract testing at the boundaries. The scenario covers behaviour end-to-end, the contract test covers the interface. Both apply. Neither replaces the other.

The discipline reduces to four words on the conference room wall: write the example, agree the example, automate the example, run the example. The scenario is the spec. The spec is the contract. The contract is in CI. Same operating principle as TS1, focused on the form the artefact takes when stakeholders read it.

§7

Notes

  1. [1]Gojko Adzic: Specification by Example: How Successful Teams Deliver the Right Software (Manning, 2011). Codifies the practice as seven process patterns and is the canonical reference for the term itself.
  2. [2]Cucumber documentation: “Writing Better Gherkin”. The declarative-versus-imperative rule in Cucumber’s own words: scenarios should describe the intended behaviour rather than the implementation.
  3. [3]Hillel Wayne: “Why Don’t People Use Formal Methods?” (hillelwayne.com, 2019). The natural-language-spec critique: examples cannot encode invariants, only their instances.
Disagree? Found a hole in the argument? Take issue with this tenet →
Last revised: 2026-10-13