TDD, BDD, DDD, SDD: Comparing Software Development Methodologies
The core ideas behind TDD, BDD, DDD and SDD, the Red-Green-Refactor cycle, and when each one applies
Contents
What a design methodology asks you to define first is what shapes your code quality and your architecture.
TDD starts from a test, BDD from a behavior specification, DDD from a domain model, and SDD from a specification.
TDD (Test Driven Development)
Kent Beck introduced it as a core practice of Extreme Programming (XP) on the Chrysler Comprehensive Compensation (C3) project.
- Write no production code until you have a failing automated test.
- Remove duplication.
The goal is to give developers psychological safety and confidence. Writing a failing test first is the act of defining a clear, executable specification for the feature. It also makes you follow the YAGNI (You Ain't Gonna Need It) principle naturally.
The Red-Green-Refactor Cycle
The core mechanism of TDD: a feedback loop that builds and improves software incrementally through short, repeated cycles.
| Stage | Description | Point |
|---|---|---|
| Red | Write a failing test. Define the API design, inputs, and expected results up front | Confirms the test system itself works |
| Green | Pass the test with the minimum code. Hardcoding and throwaway code are allowed | Focus on satisfying the functional requirement |
| Refactoring | Improve the internal structure without changing behavior. Remove duplication, improve readability, apply design patterns | The reason TDD is called a design methodology |
Effect on Architecture
- Enables evolutionary design
- The constraint of writing tests pushes the system into small, loosely coupled components
- One huge function splits into small ones; external dependencies move to Dependency Injection (DI)
BDD (Behavior Driven Development)
Dan North created it to address the difficulty in TDD of knowing what to test.
Instead of the word "test", it uses behavior, example, and specification to shift the frame to the business point of view. The core philosophy is that software development is a process of collaboration and communication aimed at a business goal, not a technical implementation exercise.
Gherkin DSL
A domain-specific language (DSL) that describes system behavior in something close to natural language.
| Keyword | Role |
|---|---|
| Feature | Overall description of the feature, in user story form (As a [role], I want [capability], so that [benefit]) |
| Scenario | A concrete example of behavior the feature must have |
| Given | Initial context before the scenario starts (setting up system state) |
| When | A user action or a system event |
| Then | Verification of the expected result or state change after the behavior |
| And, But | Connectors for Given/When/Then clauses |
Feature: User login
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters a valid ID and password
And clicks the login button
Then the user should be redirected to the dashboard pageThe Given in the example maps to Given in the table (initial context), When to the user action, and Then to verification of the expected result. A specification written in Gherkin is itself the ubiquitous language, and because it wires directly into automated test code it becomes living documentation.
Effect on Architecture
- Encourages outside-in development: work from the system's outer boundary (API, UI) inward
- User-centered interfaces: the external contract is determined directly by user requirements
- Reinforces YAGNI: only the code needed to support the specified behavior gets written
- Separation of concerns: fits naturally with hexagonal architecture
FastAPI and Pytest-BDD in Practice
GitHub: https://github.com/Jonggkwan/BDD_FastAPI
An example of building a FastAPI payment processing feature with a BDD approach:
- Write the feature file -> define the business requirement in Gherkin
- Step definitions -> map each step to a Python function with pytest-bdd
- Implement the application code -> write the FastAPI endpoints that make the scenario pass
- Run and verify the tests -> automated verification of the business requirement
DDD (Domain-Driven Design)
DDD is the design philosophy Eric Evans set out in 2003. It moves the focus of software development from technical concerns such as the database or the framework to the domain itself.
The success of a complex application depends not on technical sophistication but on how deeply the business domain is understood and how accurately it is modeled.
Strategic DDD Patterns
These focus on drawing the big picture of the system and splitting complexity into parts.
| Pattern | Description |
|---|---|
| Ubiquitous Language | A single, strict language shared by every participant, used identically in meetings, documents, and code |
| Bounded Context | An explicit boundary within which a particular domain model stays consistent |
| Context Map | A visual representation and definition of the relationships between bounded contexts |
The main relationship patterns in a context map: partnership, shared kernel, customer-supplier, and anticorruption layer.
Tactical DDD Patterns
| Pattern | Description |
|---|---|
| Entity | An object defined by a unique identity. Attributes may change, but the identity does not |
| Value Object (VO) | An immutable object defined only by its attribute values, with no identity |
| Aggregate | A cluster of related entities and value objects. The unit of consistency for data changes, accessible only through the aggregate root |
| Repository | Abstracts the persistence mechanism, separating domain logic from infrastructure |
Effect on Architecture
- Bounded contexts are the ideal basis for defining microservice boundaries
- Tactical patterns line up with the layers of clean and hexagonal architecture
- Domain layer: pure business logic (aggregates, entities, value objects)
- Application layer: use case orchestration
- Infrastructure layer: interaction with the outside world (API, DB, message queue)
Conway's Law: "Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations."
By designing a domain-centered communication structure, DDD turns Conway's Law into an advantage.
GitHub: https://github.com/Jonggkwan/DDD_FastAPI
SDD (Spec-Driven Development)
SDD writes the specification first and treats it not as a document but as the basis for code generation and verification. Combined with AI coding agents, it fixes the flow so that implementation goes through a specification rather than arriving in one shot from a vague prompt.
GitHub's Spec Kit is the representative example (MIT licensed, open source). It splits the path from specification to implementation into these stages.
| Stage | Role |
|---|---|
| specify | Define what to build: requirements and user stories |
| clarify | Fill in ambiguous parts of the specification (recommended before planning) |
| plan | Decide the technology stack and implementation strategy |
| tasks | Break the plan into executable units of work |
| implement | Execute the tasks in order to build the feature |
Because the specification becomes the single source of truth, you can fix the interface contract first as an artifact such as an OpenAPI document. You then generate the server, client, and tests against that contract. Verifying agent-generated code against a specification is what makes this a fit for environments where agent-based development is growing.
Reference:
Comparing the Methodologies
| Methodology | Starting point | Central question | Main artifacts |
|---|---|---|---|
| TDD | A failing test | "Does this code behave correctly?" | Test coverage, refactored code |
| BDD | A business scenario | "What value does this deliver to the user?" | Living documentation, acceptance tests |
| DDD | A domain model | "How should the business be modeled?" | A shared mental model, bounded contexts |
| SDD | A specification | "What interface should be provided?" | Specification documents, generated code |
Summary
The four methodologies are not competitors; they differ in where they start. Choose TDD when the goal is unit-level correctness and safe refactoring, and BDD when business requirements have to be shared with stakeholders and used as acceptance criteria. DDD fits systems where the domain is complex and modeling is itself the hard problem. SDD fits when specification-driven implementation is being automated with AI coding agents. In practice they are often combined: model the domain with DDD, specify behavior with BDD, and use TDD for the unit-level implementation inside.