Spec-Driven Development vs Test-Driven Development
Shiplight AI Team
Updated on July 15, 2026
Shiplight AI Team
Updated on July 15, 2026

Spec-driven development and test-driven development both put intent into an executable artifact before the implementation exists, but they operate at different altitudes. Test-driven development starts each small change with a failing test that pins one behavior. Spec-driven development starts a whole feature with a structured, written specification that a coding agent then plans, breaks into tasks, and implements. Test-driven development answers "does this unit do what I just claimed?" Spec-driven development answers "did we build the thing we agreed to build?" Neither replaces the other, and behavior-driven development sits between them with a shared, plain-language description of behavior.
The reason the comparison matters now is that AI coding agents changed the economics of writing that intent down. When a human wrote every line, a specification often went stale the moment coding started. When an agent reads the specification and generates the code, the specification becomes the primary input, not documentation nobody reads. That shift is why spec-driven development moved from a nice practice to a named methodology with tooling, and why teams already fluent in TDD are asking how the two fit together.
This guide defines each methodology, compares them on the axes that distinguish them, and is honest about where all three stop. The short version: writing intent down, at any altitude, does not prove the running software matches it. That gap is the subject of the last two sections.
Test-driven development is a technique for building software by writing a test before the code that satisfies it. Kent Beck developed it in the late 1990s as part of Extreme Programming and popularized it in the 2003 book Test-Driven Development: By Example, which moved the practice into the mainstream.
The rhythm is three steps, usually summarized as red, green, refactor:
The discipline is deliberately tight. Each cycle covers a single, small behavior, and the test is written by the same engineer implementing the code, in the same programming language, living beside the code in the repository. As Martin Fowler notes, the most common way to get TDD wrong is skipping the refactor step, which leaves you with a passing but messy pile of fragments.
The strength of TDD is fast, local feedback and a design pressure that pushes toward small, testable units. Its limit is scope. A green unit-test suite tells you each part does what its author claimed. It does not tell you the parts add up to the feature a product manager described, and it rarely exercises the full path a real user takes through a browser.
Behavior-driven development grew directly out of TDD. Dan North introduced it in a 2006 article as a response to a recurring problem: teams struggled with where to start testing, what to test, and how to name tests so they described behavior instead of implementation. BDD reframed a "test" as a specification of behavior written in language a non-programmer could read.
The organizing structure is Given-When-Then, a format Dan North and Chris Matts developed to break a scenario into three parts:
Dan North later formalized this into Gherkin, the structured, human-readable syntax used by tools such as Cucumber. The point of Gherkin was never the syntax. It was to create one artifact that product, QA, and engineering could all read and agree on, so that "done" meant the same thing to everyone before code was written.
BDD's contribution to the spec-versus-test question is the shared vocabulary. It raised intent from code-level assertions to plain-language scenarios, and in doing so it prefigured a lot of what spec-driven development now does at feature scale.
Spec-driven development puts a written specification at the center of the workflow and treats it as the executable source of truth that a coding agent implements from. Instead of prompting an agent feature-by-feature and hoping the result matches your intent, you describe what to build, refine it through structured phases, and let the agent generate the implementation from the refined artifact.
GitHub's open-source Spec Kit is the clearest reference implementation of the methodology. Its core loop runs in four phases, each producing a Markdown artifact that feeds the next:
Spec Kit adds one more artifact worth calling out: a constitution.md file of non-negotiable project principles that constrain every phase. The GitHub team frames the goal as making specifications executable, so they generate working implementations rather than merely guiding them. Spec Kit works with 30-plus AI coding agents, including Claude Code, GitHub Copilot, and Gemini CLI.
The altitude here is the whole difference. A TDD test pins one unit. A BDD scenario pins one user-visible behavior. A spec-driven specification pins an entire feature, including the requirements, the plan, and the task breakdown, and hands all of it to an agent as structured context instead of an ad-hoc prompt.
The three methodologies are easy to conflate because all of them write intent down first. They differ sharply on who writes it, at what granularity, and what the resulting artifact actually checks.
| Axis | Test-driven development | Behavior-driven development | Spec-driven development |
|---|---|---|---|
| What is written first | A failing unit test | A Given-When-Then scenario | A feature specification, plan, and task list |
| Granularity | One small unit behavior | One user-visible behavior | A whole feature or system slice |
| Who authors it | The implementing engineer | Engineering plus product and QA together | A human, refined with an AI agent |
| Language | The production programming language | Structured plain language (Gherkin) | Structured Markdown prose |
| Where it lives | Beside the code, in the repo | In feature files in the repo | In a spec directory in the repo |
| What it verifies | The unit does what its author claimed | The scenario behaves as described | The build matches the agreed feature |
| Primary feedback loop | Seconds, at the developer's desk | Minutes, at the acceptance level | Per feature, before and during implementation |
Read across the rows and a pattern appears. As you move from TDD to BDD to SDD, the artifact rises in altitude and widens its audience, from one engineer's local check to a cross-functional agreement to a full feature contract an agent can execute. What none of the columns guarantees on its own is the row that matters most to a user: that the running application, in a real browser, does what the artifact says.
Every methodology here is a way of making intent executable before or alongside the code. That is a genuine strength, and it is exactly why teams should keep doing it. But each one verifies a proxy for the real thing:
In an agent-speed world this gap widens fast. When an agent ships a UI change every few minutes, the question is not "was there a spec?" or "did the units pass?" It is "does the running software still match the intent right now?" Answering that reliably needs a fast verification loop that exercises the real product, not a stand-in.
This is the layer Shiplight provides, and it is deliberately methodology-agnostic. Shiplight plugs into your coding agent as an MCP server and gives it eyes and hands in a real browser. When the agent makes a change, /shiplight verify confirms the UI actually looks and behaves right, in context, before a reviewer ever sees the pull request. The acceptance criteria you already wrote, whether they came from a TDD story, a Gherkin scenario, or a spec-driven feature file, become maintained end-to-end tests through /shiplight create-yaml-tests, where the agent walks the app and authors them for you.
Those tests are readable YAML authored from intent rather than brittle selectors, they live in your own git repository, and they self-heal in a real browser with heals surfacing as reviewable pull request diffs instead of silent rewrites. That design lets acceptance criteria stay executable as the product moves, which is the same promise TDD, BDD, and SDD each make at their own altitude.
These are not mutually exclusive, and the strongest teams compose them. Run spec-driven development at the feature level to align on what to build, keep test-driven development at the unit level for fast local design feedback, and borrow BDD's Given-When-Then to phrase acceptance criteria both humans and agents can read. The methodologies stack because they operate at different granularities.
What none of them supplies is proof at the top of the stack. A specification, a scenario, and a unit test are all statements of intent. The one thing an agent-speed team cannot skip is a loop that checks the running product against that intent continuously, in the browser a customer would actually use. For more, see the executable intent playbook and the tradeoffs between AI-generated and hand-written tests. New to the top of this stack? Start with what spec-driven development is and how test-driven development changes in the AI era.
Spec-driven development starts a feature with a written specification that a coding agent plans and implements, so intent is captured at the feature level. Test-driven development starts each small change with a failing unit test that the same engineer then makes pass, so intent is captured at the unit level. They operate at different altitudes and can be used together on the same project.
No, though they share DNA. Behavior-driven development, introduced by Dan North in 2006, describes individual behaviors in Given-When-Then form for a shared human-readable acceptance check. Spec-driven development captures a full feature, including requirements, a technical plan, and a task breakdown, and is designed for an AI coding agent to implement from directly.
No. The three compose well because they work at different granularities. Many teams run spec-driven development at the feature level, test-driven development at the unit level, and borrow BDD's Given-When-Then to phrase acceptance criteria that both people and agents can read.
Not by itself. A specification, a scenario, and a unit test are all statements of intent, and each verifies a proxy for the running product. Proving the live application matches that intent requires a verification loop that exercises the real UI in a browser, which is what Shiplight adds on top of whichever methodology you use.
Shiplight is methodology-agnostic. It plugs into your coding agent to verify UI changes in a real browser as they are built, then turns your acceptance criteria into maintained end-to-end tests written as readable YAML in your own repository. Whether the intent came from TDD, BDD, or spec-driven development, Shiplight closes the loop by proving the running software matches it.