Мариам получила задачу, которую никто не хотел брать: рефакторинг системы бронирования, написанной пять лет назад.
15000 строк кода. Ноль тестов. Оригинальный разработчик давно уволился. Документация — только комментарии в коде, и те на смеси грузинского и английского.
Первая попытка: написать тесты для текущего кода
Мариам решила начать логично — покрыть существующий код тестами, потом рефакторить.
Открыла файл BookingService.js — 800 строк в одной функции. Внутри 15 условных операторов, прямые запросы к базе, вызовы внешних API, форматирование для фронтенда.
| Проблема | Проявление | Решение |
| Гигантские функции | Невозможно протестировать изолированно | Разбить на маленькие перед тестами |
| Глобальное состояние | Функции зависят от порядка вызова | Переписать с явными параметрами |
| Смешанная логика | Бизнес-логика + БД + UI в одном месте | Разделить по слоям |
| Неявные зависимости | Магические константы из конфига | Внедрить через параметры |
Мариам поняла: чтобы написать тесты, придется сначала рефакторить. Но рефакторить без тестов опасно — можно сломать работающую функциональность.
Стратегия: характеризационные тесты
Ментор посоветовал книгу Working Effectively with Legacy Code.
Идея: написать тесты, которые фиксируют текущее поведение системы, даже если оно неправильное. Потом безопасно рефакторить.
Мариам начала с критического флоу — создание бронирования. Запустила код с разными параметрами и записала результаты:
- Корректные данные — бронирование создается, ID возвращается
- Дата в прошлом — система создает бронирование (баг!)
- Несуществующий номер — возвращает 500 ошибку (тоже баг)
- Дублирующее бронирование — перезаписывает старое (еще один баг)
Она написала тесты, которые проверяли именно это поведение — включая баги.
Процесс рефакторинга под защитой тестов
Мариам работала маленькими шагами.
| Неделя | Действие | Покрытие | Найденные регрессии |
| 1 | Характеризационные тесты главного флоу | 12% | 0 |
| 2-3 | Извлечение функций валидации | 28% | 2 (поймали тестами) |
| 4-5 | Разделение слоев БД и бизнес-логики | 45% | 4 (поймали тестами) |
| 6-7 | Рефакторинг бизнес-логики | 67% | 1 (поймали тестами) |
| 8 | Исправление исходных багов | 71% | 0 |
Каждое изменение проверялось тестами. Семь раз тесты падали — Мариам случайно меняла поведение. Без тестов эти баги ушли бы в продакшн.
Неожиданное открытие
На шестой неделе Мариам обнаружила странность.
Функция расчета стоимости бронирования добавляла 15% к итоговой сумме. Никакого комментария. Она написала тест, зафиксировала поведение и спросила у менеджера.
Оказалось, это костыль пятилетней давности для компенсации бага в другом модуле. Тот модуль давно переписали, но надбавку забыли убрать. Компания пять лет теряла клиентов из-за завышенных цен.
Мариам поняла: тесты для легаси-кода — это не только защита при рефакторинге, но и способ задокументировать неочевидное поведение системы
Финальный результат
Через два месяца модуль бронирования имел 71% покрытие тестами и читаемый код.
Мариам не стремилась к 100% — некоторые куски легаси настолько запутаны, что дешевле переписать с нуля с тестами, чем тестировать как есть.
Главный урок: добавление тестов в старый код требует другого подхода, чем TDD для нового. Характеризационные тесты фиксируют текущее поведение. Только потом можно безопасно менять архитектуру.