← Testing and quality guides

How to use SpecDD with TDD

How-To Testing and quality Intermediate 1131000HOWTO-1131000

HOWTO-1131000Testing and qualityIntermediate

This guide shows you how to use SpecDD with test-driven development.

TDD is strongest when the behavior being tested is already clear. SpecDD gives that clarity by defining the durable contract: what the subject owns, what it must do, what it must not do, and what counts as done. TDD then turns part of that contract into executable feedback.

The combined workflow is simple: review the spec, derive one test, make it pass, refactor inside the boundary, and keep the spec, task status, and tests aligned.

Short answer

Start from a reviewed spec, not from a vague prompt. Pick one Must, Scenario, Handles, Raises, Returns, or Done when entry. Write a failing test that proves that behavior. Implement only enough code to pass while staying inside Owns or Can modify and respecting Must not and Forbids. Then refactor, rerun checks, and update local tasks only after verification passes.

When to use this guide

Use this guide when:

The workflow

1. Review the spec first

Before writing a test, confirm the spec is ready:

Example:

Spec: Itinerary Validation

Purpose:
  Decide whether an itinerary item can be saved.

Owns:
  ./itinerary-validation.js
  ./itinerary-validation.test.js

Must:
  Reject itinerary items without a place name.
  Preserve existing itinerary items when validation fails.

Must not:
  Save itinerary items directly.

Scenario: missing place name
  Given the place name is empty
  When the person adds the itinerary item
  Then validation fails
  And no itinerary item is stored

Done when:
  Missing-place validation is covered by a check.

This is a good TDD source because it names the unit, the behavior, the forbidden effect, and the needed check.

2. Choose one behavior

Do not start by testing the whole spec. Pick one behavior:

Missing place name is rejected and the itinerary remains unchanged.

This keeps the TDD loop small and makes failures easier to interpret.

3. Write the failing test

The test should prove behavior, not spec wording:

Rejects an itinerary item without a place name and leaves existing items unchanged.

Avoid tests that assert implementation detail:

Uses validatePlaceName before saveItinerary.

That may over-constrain the implementation unless the call order is part of the spec.

4. Implement inside spec authority

Make the smallest implementation change that satisfies the test and the spec.

Check:

Passing the test is not enough if the code violates Must not or Forbids.

5. Refactor without crossing boundaries

After the test passes, refactor if needed. The refactor must still preserve:

If refactoring requires moving behavior to another owner, stop and update or add the owning spec first.

6. Update tasks after checks pass

If the spec contains:

Tasks:
  [ ] Add missing-place validation.

mark it done only after:

Tasks are not done because code was written. They are done because specified behavior has been implemented and checked.

Working with an agent

Useful focused prompts:

Write the failing test for missing-place itinerary validation.
Implement the missing-place itinerary validation behavior.
Review the Itinerary Validation change against its spec and tests.

Keep each prompt to one action. Review the output before moving to the next step.

Common mistakes

How to verify the result

SpecDD and TDD are working together when:

← Testing and quality guides