jongkwan.dev
Development · Essay №017

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

Jongkwan Lee2025년 8월 30일8 min read
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.

  1. Write no production code until you have a failing automated test.
  2. 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.

StageDescriptionPoint
RedWrite a failing test. Define the API design, inputs, and expected results up frontConfirms the test system itself works
GreenPass the test with the minimum code. Hardcoding and throwaway code are allowedFocus on satisfying the functional requirement
RefactoringImprove the internal structure without changing behavior. Remove duplication, improve readability, apply design patternsThe 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.

KeywordRole
FeatureOverall description of the feature, in user story form (As a [role], I want [capability], so that [benefit])
ScenarioA concrete example of behavior the feature must have
GivenInitial context before the scenario starts (setting up system state)
WhenA user action or a system event
ThenVerification of the expected result or state change after the behavior
And, ButConnectors for Given/When/Then clauses
gherkin
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 page

The 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:

  1. Write the feature file -> define the business requirement in Gherkin
  2. Step definitions -> map each step to a Python function with pytest-bdd
  3. Implement the application code -> write the FastAPI endpoints that make the scenario pass
  4. 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.

PatternDescription
Ubiquitous LanguageA single, strict language shared by every participant, used identically in meetings, documents, and code
Bounded ContextAn explicit boundary within which a particular domain model stays consistent
Context MapA 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

PatternDescription
EntityAn 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
AggregateA cluster of related entities and value objects. The unit of consistency for data changes, accessible only through the aggregate root
RepositoryAbstracts 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.

StageRole
specifyDefine what to build: requirements and user stories
clarifyFill in ambiguous parts of the specification (recommended before planning)
planDecide the technology stack and implementation strategy
tasksBreak the plan into executable units of work
implementExecute 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

MethodologyStarting pointCentral questionMain artifacts
TDDA failing test"Does this code behave correctly?"Test coverage, refactored code
BDDA business scenario"What value does this deliver to the user?"Living documentation, acceptance tests
DDDA domain model"How should the business be modeled?"A shared mental model, bounded contexts
SDDA 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.