---
title: "Разработка через тестирование"
type: "architectural-pattern"
slug: "test-driven-development"
url: "http://localhost:3000/ru/architectural-patterns/test-driven-development.md"
also_known_as: "TDD, Red-Green-Refactor"
description: "Дисциплина разработки, при которой вы пишете падающий тест до кода, который заставит его пройти, а затем рефакторите — позволяя тестам управлять дизайном в коротких, плотных циклах."
languages: ["python"]
---
# Разработка через тестирование

_Also known as: TDD, Red-Green-Refactor_

> Дисциплина разработки, при которой вы пишете падающий тест до кода, который заставит его пройти, а затем рефакторите — позволяя тестам управлять дизайном в коротких, плотных циклах.

## Intent

Управляйте дизайном и проверяйте корректность кода, написав падающий тест для каждого небольшого фрагмента поведения _до_ написания кода, который ему удовлетворяет, а затем улучшая дизайн, пока тесты держат вас в безопасности.

## Problem

Код, написанный без тестов, рискованно менять: нет быстрого способа узнать, не сломала ли правка что-нибудь. Тесты, написанные _постфактум_, как правило, поверхностны, подогнаны под код, который, возможно, уже трудно тестировать, и редко влияют на дизайн.

Без вынуждающего фактора дизайн также склонен разрастаться запутанным и трудным для прогона в изоляции.

## Solution

Работайте в коротком цикле **Красный — Зелёный — Рефакторинг** (Red-Green-Refactor):

1. **Красный** — напишите небольшой тест для следующего фрагмента поведения и посмотрите, как он падает.
2. **Зелёный** — напишите простейший код, который заставит тест пройти, пусть даже уродливый.
3. **Рефакторинг** — приведите код (и тесты) в порядок теперь, когда они зелёные, а набор защищает от регрессий.

Повторяйте в циклах длиной в минуты. Поскольку тесты идут первыми, код тестируем по построению, а набор документирует предполагаемое поведение.

## Structure

* **Цикл** — Красный → Зелёный → Рефакторинг, непрерывно повторяемый.
* **Список тестов** — текущий перечень поведений, которые ещё предстоит покрыть.
* **Arrange–Act–Assert** — форма сфокусированного модульного теста.
* **Тестируемый модуль** — небольшой срез поведения, который фиксирует каждый тест.

## Applicability

* Используйте её для кода с реальной **логикой и ветвлением** и для долгоживущего кода, который будет часто меняться.
* Особенно ценна там, где важны быстрая обратная связь и защита от регрессий.
* **Менее подходит** для одноразовых спайков или исследовательской работы над UI, где дизайн ещё не устоялся.

## How to Implement

1. Выберите следующее небольшое поведение из вашего списка тестов.
2. Напишите тест, утверждающий его, и запустите набор, чтобы увидеть падение (красный).
3. Напишите минимальный код, необходимый для прохождения; запустите набор (зелёный).
4. Рефакторите боевой и тестовый код, удерживая набор зелёным.
5. Повторяйте, добавляя поведения в список по мере их обнаружения.

## Pros

* Высокое покрытие тестами как побочный продукт, а не как запоздалая мысль.
* Быстрая обратная связь ловит регрессии за секунды.
* Поощряет слабосвязанный, тестируемый дизайн.
* Набор выступает живой, исполняемой документацией.

## Cons

* Более медленный начальный темп и реальная кривая обучения.
* Может чрезмерно акцентировать изолированные модули, упуская пробелы в интеграции.
* Тесты — тоже код: их нужно сопровождать и рефакторить.
* Не заменяет исследовательское, интеграционное или сквозное тестирование.
## Relations

**Related patterns**

- [Разработка на основе спецификации](/ru/architectural-patterns/spec-driven-development.md)

## Code Examples

### python

```python
# Красный: сначала пишем падающий тест.
def test_slugify_lowercases_and_hyphenates():
    assert slugify('Hello World') == 'hello-world'

# Зелёный: простейший код, который проходит.
def slugify(text: str) -> str:
    return text.lower().replace(' ', '-')

# Рефакторинг позже (например, убрать пунктуацию), а тест служит страховкой.
```

