Specroot Waitlist open

Spec-driven development vs TDD vs BDD: one requirement written three ways

Spec-driven development, TDD and BDD are not three ways to do the same thing; they answer different questions, and with an AI coding agent they fit together in a chain. The spec says what to build, why, and who agreed. A BDD scenario turns one of its acceptance cases into an example the business can read and a tool can run. A test pins the behaviour down in code, so the agent knows when it is done and finds out when it breaks something. The evidence so far favours putting concrete, executable cases in front of the agent and having a person check them; asking the agent to follow TDD on its own showed no clear gain in an exploratory comparison. Below is one requirement written all three ways, what each one leaves out, how they chain, what the research says, and which to use when.

The spec is the intent, the written spec is an approximation of that, the tests are an approximation of that.

— Hacker News, 2026

The difference in one table

Question Answered by
What are we building, and why? The spec
Who agreed to it, and when? The spec
What is out of scope, and what must not change? The spec
What exactly happens in this case, in words the business reads? A BDD scenario
Does the code do it, today and after every change? A test
  • Spec-driven development writes the intent down before the code and builds from it: the requirement, its acceptance cases, what is out of scope. It is what an AI coding agent reads before it plans.
  • Behaviour-driven development (BDD) describes behaviour as concrete examples in Given, When, Then, agreed with the business and run as tests. Its usual format is Gherkin.
  • Test-driven development (TDD) writes a failing test before the code that makes it pass, one small step at a time, and lets the design grow from the tests.

One requirement, three ways

The payment reminder from the customer portal used across this site, as it stood after a change request: partly paid invoices now get a reminder too.

The spec. The requirement in EARS, with what only a spec holds:

FR-016, version 2

WHEN an invoice not paid in full is
seven days past its due date THE
SYSTEM SHALL send one payment reminder
to the billing contact.

Why: invoices stay unpaid too long
(BR-03).

Acceptance case 4: partly paid by
8 March, one reminder.

Out of scope: a second reminder.

Decided by the finance lead, 16 June
(D-7).

The BDD scenario. Acceptance case 4 as an example someone in finance can read and a tool such as Cucumber can run:

Feature: Payment reminder

  Scenario: Partly paid invoice
    Given an invoice of 100 due on 1 March
    And 40 was paid on 5 March
    When the reminder job runs on 8 March
    Then one reminder is sent
    And it goes to the billing contact

The test. The same case in code:

def test_partly_paid_gets_reminder():
    inv = invoice(100, due=d(3, 1))
    pay(inv, 40, on=d(3, 5))
    sent = run_reminders(on=d(3, 8))
    assert sent == [reminder(inv)]

The test is the same whether it was written before the code or after. TDD is a way of working, not a kind of test; what makes this TDD is that it existed, and failed, before the code did.

What each one leaves out

Form What it cannot say
The spec Whether the code actually does it
The scenario Why, who decided, what is out of scope — and any case nobody wrote a scenario for
The test Why, who decided — and any behaviour nobody wrote a test for

The last row matters most with an agent. Birgitta Böckeler of Thoughtworks compared agents that followed TDD with agents that did not. In the TDD runs, the design grew one test at a time, and “Behaviour the agent didn’t think to write a test for didn’t get implemented at all” (martinfowler.com, October 2026). A test suite says what was checked. The spec says what was asked for. You need both to see the gap between them.

One commenter put the hard part of TDD plainly: “The hard bit is knowing which functions to write, and what ‘valid’ means for inputs and outputs” (Hacker News, 2025). That is the part a spec writes down first.

How they chain

  1. The spec comes first, with its acceptance cases written as cases that pass or fail, with real values. The people who have to agree review it — see how to write a spec for AI agents.
  2. Each acceptance case becomes a test. If the business reads the cases, write them as Gherkin scenarios first; if not, go straight to tests. Either way, name the case each test comes from.
  3. The tests exist before the code, and fail. The agent may write the test code, but a person checks that each test asserts what its case says.
  4. The agent builds until the tests pass, and does not change a test without saying why.
  5. When the spec changes, the cases change first, then the tests, then the code. The links from step 2 tell you which tests a change touches — as in step 8 of the spec-driven development example.

Practitioners describe the same chain in one line. One commenter: “every one of my coding agent sessions starts with ‘… write a detailed spec in spec.md and wait for me to approve it’. Then I review the spec, then I tell it ‘implement with red/green TDD’” (Hacker News, 2026). Another, on why the link from case to test matters: “I always translate specs into Gherkin BDD scenarios and drive the tests off that; without this linkage test coverage diverges from user flows” (Hacker News, 2026).

The tools build parts of this chain in. Spec Kit’s spec template writes acceptance scenarios as Given/When/Then, OpenSpec’s scenarios use GIVEN, WHEN and THEN, Kiro writes requirements in EARS, and Superpowers makes the agent work test-first. How they differ is in Spec Kit vs OpenSpec vs BMAD.

What the research says

Tests in front of the agent help. On function-level tasks: “merely providing the LLM with tests during generation improves correctness by 9.15 to 29.57%” (Mathews and Nagappan, ASE 2024). On real repositories, an agent workflow given the tests people had written for each issue reached a 94.3% pass rate on SWE-bench Verified; its authors “envision a human-LLM interactive system powered by TDFlow where human developers write tests solved by LLM systems” (Han et al., EACL 2026). Those were the benchmark’s own tests, an idealised setting.

Concrete cases matter more than stated requirements. In 2,700 runs built on Spec Kit’s spec template, removing the Given/When/Then acceptance scenarios made the agent work longer, while removing the prose success criteria made no measurable difference: “What matters is concreteness about which cases must pass, not the presence of a stated requirement” (Smékal, 2026, preprint, five tasks).

Gherkin is not a magic format. In a small pilot that generated business logic for three systems, adding structured input of any kind improved the share of tests passed over a prose description alone. But Gherkin scenarios in place of the prose, each alongside a domain model, did slightly worse on average — a 6.8% lower test pass rate — while winning in 14 of 30 combinations (Feng et al., FSE 2026).

TDD inside the agent’s loop shows no clear gain. Böckeler’s exploratory comparison, which she calls “a very small sample size”, found “no clearly discernable difference based on TDD workflow versus no TDD workflow”, at least three times the tokens for TDD, and agents that “frequently overshot and implemented more than the current test demanded, because they had the full requirement available.” Her conclusion is about where TDD’s value went: the friction of thinking through behaviour in small steps “is theoretically shifting to when we are writing the specs to give to an agent.”

Put together: what helps is executable cases a person has checked, in front of the agent. Whether the agent writes its tests first or last inside its own loop matters much less.

Who writes the tests

Böckeler describes three ways to combine TDD with an agent: a person writes the tests; the agent writes a failing test and a person reviews it before the code; or the agent does the whole loop itself. “At this stage, that last usage is by far the most common one.”

The risk in that third way is the one testing has always had. One commenter: “The failure mode here is letting the AI manage both the implementation and the testing. May as well ask high schoolers to grade their own exams” (Hacker News, 2026). If the agent misreads the case, its code and its test agree with each other and both are wrong — and the suite is green.

A workable split: the person who agreed to the spec owns the acceptance cases; the agent may write the test code; a person checks that each test asserts its case before the build starts. That check is quick when each test names its case, as in the chain above.

Where BDD fits now

BDD began as a way to agree on behaviour through examples: Dan North and the business analyst Chris Matts made Given/When/Then a template for a story’s acceptance criteria (Introducing BDD, 2006). With agents, the scenario is still the most readable executable form of an acceptance case — worth writing when someone outside the team reads the cases, and an overhead when nobody does. The keywords, templates and pitfalls are in Gherkin examples.

Some tools go a step further than examples. Kiro turns requirements into property-based tests: in its own documentation, “Instead of listing examples, you state a general rule that must always hold, and the tool generates hundreds or thousands of random inputs to try to violate it” (Kiro, vendor documentation). For the reminder, a property would be for any invoice not paid in full and seven days past due, exactly one reminder is sent — checked against many invoices, not one. Properties suit rules with many inputs: prices, dates, limits.

Not a new idea

In 2004, Jonathan Ostroff, David Makalsky and Richard Paige described “an agile approach to Specification-Driven Development, which combines features of Test-Driven Development and the plan-based approach of Design-by-Contract” (XP 2004). One commenter on r/agile remembered it: “Years ago there was a technique called spec driven development that people used much like ATDD and BDD. I didn’t realize someone had created a tool for AI with the same name” (r/agile, 2026).

There is a real difference in direction. Another commenter: “Spec Driven Development is a curious term - it suggests it is a kind of, or at least in the tradition of, Test Driven Development but it goes in the opposite direction!” (Hacker News, 2026). TDD lets the design emerge from small tests; spec-driven development writes the intent down first and builds from it. The two meet at the acceptance cases: the spec states them, the tests check them. More on the history and the tools in what spec-driven development is.

Which to use when

Situation Use
A bug A failing test that reproduces it; no spec
A change someone else has to agree to A spec with acceptance cases, then tests from the cases
The business reads the acceptance cases Write the cases as Gherkin scenarios
A rule with many inputs: prices, dates, limits Add property-based tests
A prototype you may throw away Neither, until you decide to keep it

Where Specroot fits

This is the problem Specroot works on: the link between what was agreed and what is tested — each acceptance case kept with its requirement and the decision behind it, so that a changed case leads to the tests that check it. Specroot for teams using AI coding agents.

  • Gherkin examples — Gherkin examples to copy: the keywords, a full feature file, Scenario Outline with Examples, data tables, Background, Rule, a template and best practices.
  • EARS requirements: syntax and examples — EARS requirements syntax: the five patterns with examples, a template to copy, how to rewrite a requirement in EARS, EARS vs Gherkin, and EARS in Kiro.
  • Acceptance criteria template: Given/When/Then examples — Free acceptance criteria templates (Given/When/Then and checklist), with examples for user stories and APIs, and how they differ from the definition of done.
What Specroot is