Четыре подхода, которые не конкурируют

В прошлом уроке мы разобрали, что спека — источник истины, а код — артефакт сборки. Теперь закономерный вопрос: чем это отличается от TDD, где «тест — источник истины»? Или от BDD с его «требованиями на языке бизнеса»?

Если не разобраться с этим сразу, SDD будет казаться очередным переименованием старых идей. Это не так — давайте разложим по осям.

Три оси сравнения

Зафиксируем три вопроса, по которым подходы реально различаются:

1. Уровень: функция/класс или система в целом?

2. Кто исполняет: разработчик, команда или AI-агент?

3. Что фиксируем: тест, сценарий поведения или системное требование?

flowchart TD subgraph ByDev["Исполняет: разработчик"] TDD["TDD<br>Уровень: функция/класс<br>Фиксирует: тест-assert"] BDD["BDD<br>Уровень: поведение фичи<br>Фиксирует: Given/When/Then"] end subgraph ByHuman["Читают: люди"] DD["Design doc<br>Уровень: система<br>Фиксирует: архитектуру"] end subgraph ByAgent["Исполняет: AI-агент"] SDD["SDD<br>Уровень: система/фича<br>Фиксирует: требование + критерии"] end SDD -->|"порождает"| TDD SDD -. "включает идеи" .-> DD
flowchart TD
    subgraph ByDev["Исполняет: разработчик"]
        TDD["TDD<br>Уровень: функция/класс<br>Фиксирует: тест-assert"]
        BDD["BDD<br>Уровень: поведение фичи<br>Фиксирует: Given/When/Then"]
    end
    subgraph ByHuman["Читают: люди"]
        DD["Design doc<br>Уровень: система<br>Фиксирует: архитектуру"]
    end
    subgraph ByAgent["Исполняет: AI-агент"]
        SDD["SDD<br>Уровень: система/фича<br>Фиксирует: требование + критерии"]
    end
    SDD -->|"порождает"| TDD
    SDD -. "включает идеи" .-> DD
Четыре подхода по трём осям: уровень, адресат, что фиксируем. SDD порождает TDD-тесты и вбирает архитектурные решения из design doc.

TDD: тугой цикл на уровне кода

TDD — дисциплина разработчика, а не агента. Цикл Red–Green–Refactor занимает минуты: написал тест для одной функции → убедился, что он падает → написал реализацию → тест проходит → подчистил.

Классический цикл TDD: тест падает (Red) → реализация (Green) → рефакторинг (Refactor) — и снова по кругу.Source: cleancodeguy.com

Главное: TDD работает на уровне конкретного кода. «Тест» здесь — это буквальный вызов функции с проверкой результата:

def test_password_hashed():
    result = hash_password("secret")
    assert result != "secret"
    assert len(result) > 20

Никакого агента. Разработчик пишет тест, видит красный прогон, пишет реализацию. TDD — про внутреннюю дисциплину написания кода, а не про то, что строить на уровне системы.

Check yourself
Если бы вы применили TDD к задаче «регистрация через email», что именно стало бы первым артефактом? Попробуйте ответить до того, как перейдёте к следующему разделу.

BDD: поведение на языке бизнеса

BDD вырос из TDD — как попытка поднять разговор на уровень выше. Синтаксис Given/When/Then (Gherkin) читаем не только разработчикам, но и менеджерам:

Scenario: Регистрация с уникальным email
  Given пользователь ещё не зарегистрирован
  When он отправляет форму с email "user@example.com" и паролем "securePass1"
  Then система создаёт учётную запись
  And отправляет письмо с подтверждением

По оси «уровень» BDD поднимается выше TDD — фича целиком, а не одна функция. Но по оси «кто исполняет» — всё ещё разработчик: он пишет step definitions, которые превращают Gherkin-шаги в вызовы кода. Cucumber или pytest-bdd прогоняют сценарий как тест в CI.

Адресаты BDD — разработчик и бизнес. Но это всё равно тест, который команда поддерживает вручную.

Check yourself
BDD и SDD оба описывают поведение системы в читаемом виде. В чём их принципиальное отличие по оси «адресат»?

Design doc: документ для людей

Design doc описывает, почему выбрали Redis вместо Memcached, как устроены компоненты, какие компромиссы приняты. Его читают люди — и только люди.

Ключевое отличие: design doc не исполняется никаким инструментом. CI его не прогоняет. Он может устареть, и никто не заметит, пока не прочитает и не удивится расхождению с кодом. По оси «кто исполняет» design doc вообще вне игры.

SDD: требования для агента

SDD занимает другое место по всем трём осям:

  • Уровень — системный: спека описывает поведение фичи целиком, включает NFR, ограничения, edge-кейсы.
  • Кто исполняет — AI-агент. Спека — структурированный контекст, который агент читает и превращает в код.
  • Что фиксируем — требование плюс acceptance criteria плюс архитектурные решения — всё в одном месте.

Разница с design doc: спека предназначена для исполнения. Разница с BDD: спека — не тест, она порождает тесты как один из артефактов.

Quick recall
Какой синтаксис используется в BDD, и почему это важно для бизнеса?
Quick recall
Какой ключевой процесс описывает дисциплину TDD?

SDD порождает TDD-тесты

Это, пожалуй, главное, что нужно понять: SDD и TDD не конкурируют — они встроены в цепочку.

Вернёмся к примеру из прошлого урока. Спека содержит:

### FR-01 Регистрация через email
WHEN пользователь отправляет форму с email и паролем
THE SYSTEM SHALL создать учётную запись и отправить письмо с подтверждением.

Acceptance criteria:
- [ ] Дублирующийся email возвращает ошибку 409
- [ ] Пароль не менее 8 символов
- [ ] Письмо отправляется в течение 30 секунд

Когда агент получает задачу «написать тесты», он берёт каждый пункт acceptance criteria и превращает его в конкретный тест:

def test_duplicate_email_returns_409():
    create_user(email="user@example.com")
    response = client.post("/auth/register", json={
        "email": "user@example.com",
        "password": "securePass1"
    })
    assert response.status_code == 409

def test_password_min_length_8():
    response = client.post("/auth/register", json={
        "email": "new@example.com",
        "password": "short"
    })
    assert response.status_code == 422

Агент не выдумывает edge-кейсы — он трассирует их из спеки. Это принципиальное отличие от vibe coding, где тесты пишутся «по мотивам кода». Здесь тест отражает намерение, зафиксированное до написания строчки реализации.

Check yourself
Посмотрите на три пункта acceptance criteria в примере выше (409, 8 символов, 30 секунд). Сколько тестов должен сгенерировать агент — и почему именно столько?
Quick recall
Почему тесты, порождённые из SDD-спеки, лучше отражают намерение, чем тесты написанные после реализации?

Сводная таблица

TDDBDDDesign docSDD
Уровеньфункция/классповедение фичисистемасистема/фича
Адресатразработчикразработчик + бизнескоманда (читают)AI-агент
Что фиксируемassertGiven/When/Thenархитектурное решениетребование + критерии
Исполняется в CIдаданетда (агентом)
Порождает тестыявляется тестомявляется тестомнетда, как артефакт

Итог

Когда говорят «SDD — это как TDD, только для агентов» — это неточно в обе стороны. TDD работает на уровне функции и предполагает человека за рулём. SDD работает на уровне системы и адресован агенту. Но они прекрасно сочетаются: SDD-спека порождает TDD-тесты как артефакт, BDD-сценарии могут войти в acceptance criteria, а design.md в Kiro — это эволюция design doc, предназначенная для чтения агентом, а не только людьми.

В следующем уроке разберём анатомию рабочей спеки изнутри: файлы Kiro, нотацию EARS и как выглядит спека, которая действительно помещается в голову.