12
0
0
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
Назад

«Вчера было надо»: стратегия тестирования в условиях живого легаси-кода

Время чтения 5 минут
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
12
0
0
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники

Привет! Меня зовут Алексей Кононов, я ведущий инженер разработки центра экспертизы веб-разработки дистанционных каналов Газпромбанка. В статье расскажу о тестировании в условиях «вчера было надо»: как покрывать тестами легаси-код и не сойти с ума. В своей ежедневной работе я напрямую отвечаю не только за реализацию функциональности, но и за стабильность продукта в продакшене, качество релизов и снижение регрессий. В условиях активного развития продукта и наличия значительного легаси-кода тестирование становится для разработчика не отдельной дисциплиной, а практическим инструментом управления рисками, безопасного рефакторинга и поддержки скорости изменений.

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

Фронтенд на React и TypeScript живет годами, проходит через десятки релизов, смену команд и архитектурных подходов. Легаси в такой системе — не исключение, а нормальное состояние. При этом бизнес часто требует изменений «нужно уже вчера». В этих условиях тестирование перестает быть формальной практикой и становится инструментом инженерной устойчивости.

«Вчера было надо»: стратегия тестирования в условиях живого легаси-кода

Легаси как результат эволюции продукта

Легаси редко возникает из-за слабых решений. Чаще это следствие естественной эволюции продукта: быстрые запуски, рост нагрузки, появление новых требований по безопасности, регуляторике и пользовательскому опыту. Во фронтенде это особенно заметно, потому что интерфейс — точка пересечения всех изменений.

В одном React-приложении могут сосуществовать разные подходы к управлению состоянием (Redux, Context API, mobX), несколько поколений архитектурных решений, старые API и новые контракты. Со временем растет связанность, появляются неявные зависимости и побочные эффекты. Изменение одного компонента способно затронуть десятки экранов и пользовательских сценариев.

Инженерная проблема легаси заключается не в «возрасте» кода, а в потере предсказуемости. Когда разработчик не может уверенно оценить последствия изменений, скорость разработки падает, а риск инцидентов растет. Именно здесь автоматические проверки начинают играть роль инструмента восстановления управляемости системы.

Почему проценты покрытия не решают проблему

Одна из типичных ошибок — попытка лечить легаси через увеличение метрик. В одном из проектов мы активно наращивали юнит-покрытие компонентов, проверяя внутренние состояния и структуру DOM. Формально показатели выглядели отлично (80+%), но на практике:

  • тесты ломались при любом рефакторинге;
  • поддержка тестов занимала больше времени, чем разработка;
  • CI замедлился на 15+ минут;
  • команда начала воспринимать тесты как помеху.

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

Стратегия работы с легаси в условиях продакшена

Когда код уже находится в продакшене, активно развивается и при этом практически не покрыт тестами, важно действовать последовательно и прагматично. Попытка одномоментно «оздоровить» всю кодовую базу — резко увеличить покрытие, переписать архитектуру или ввести тяжелые процессы — почти всегда заканчивается срывом сроков и конфликтом с бизнес-ожиданиями. В живом продукте невозможно просто «поставить разработку на паузу» ради технического долга.

Именно поэтому на практике эффективнее работает пошаговая стратегия: когда команда постепенно фиксирует качество нового кода, защищает наиболее рискованные участки и только затем аккуратно улучшает архитектуру, не ломая ритма релизов и инженерных процессов.

Фиксация качества нового функционала

Первое правило: весь новый код сразу сопровождается автоматическими проверками. Это позволяет остановить рост технического долга, даже если старый код пока остается без покрытия.

Во фронтенде это обычно выглядит так:

  • юнит-тесты бизнес-логики на Jest;
  • поведенческие тесты компонентов через React Testing Library;
  • E2E-сценарии пользовательских потоков в Playwright + Cucumber.

Практический кейс: при реализации QR-оплаты с парсингом PDF417 на клиенте, с доступом к камере и с динамической генерацией форм были добавлены E2E-сценарии на edge-кейсы — офлайн-режим, слабый сигнал, нестабильная камера. Несколько потенциальных регрессий были выявлены еще до выхода в продакшен.

Даже минимальный набор таких проверок резко снижает риск инцидентов.

Изоляция и защита критических модулей

Следующий фокус — зоны с максимальной стоимостью ошибки:

  • аутентификация и безопасность;
  • финансовые операции;
  • сложные формы и валидации;
  • интеграции с внешними сервисами;
  • модули с высокой частотой изменений.

Для этих участков важно минимизировать связанность, выделять стабильные интерфейсы и закрывать поведение интеграционными и E2E-тестами. Даже несколько стабильных сценариев дает больше уверенности, чем сотни низкоуровневых проверок.

Фиксация текущего поведения как точка опоры

Когда архитектура сложная и плохо документированная, полезно сначала зафиксировать текущее поведение системы. Во фронтенде это достигается через snapshot-проверки сложных экранов, E2E-сценарии реальных пользовательских потоков и тестирование публичных контрактов компонентов.

Этот подход позволяет безопасно вносить изменения, не опасаясь скрытых регрессий. Подобная стратегия подробно описана Майклом Физерсом в книге Working Effectively with Legacy Code, где вводится понятие characterization tests.

Безопасный рефакторинг без остановки релизов

Под защитой базовых проверок становится возможным аккуратный рефакторинг:

  • вынос бизнес-логики из UI-компонентов;
  • снижение связанности и переход на микрофронтенды;
  • внедрение адаптеров и фасадов;
  • явное разделение ответственности слоев.

Практический пример — внедрение Feature-Sliced Design в легаси-монолите: сотни код-ревью, поэтапная реструктуризация по фичам и вынос крупных разделов в микрофронтенды, снижение связанности без остановки релизов и без роста регрессий. Опыт и архитектурные выводы были представлены в инженерном докладе Газпромбанк.Тех на FrontendConf 2024.

Важно избегать крупных переписываний: в живом продукте гораздо надежнее эволюция небольшими итерациями.

Когда контроль превращается в тормоз

Избыточное количество низкоуровневых тестов может парализовать развитие. В одном из проектов любое изменение требовало переписывания десятков проверок, привязанных к деталям реализации (CSS-классы, DOM-структура). В итоге около 70% таких тестов были удалены, а акцент смещен на проверку поведения системы во время пользовательского сценария.

Этот опыт показал, что инженерный баланс важнее формальных показателей.

Инженерная дисциплина и доверие к автоматике

Автоматические проверки работают только при дисциплине:

  • обязательный запуск в CI;
  • устранение нестабильных тестов;
  • минимальный набор E2E-сценариев перед релизом.

Когда разработчик доверяет автоматике, он может смелее улучшать код и быстрее выпускать изменения.

Вывод

Тестирование в условиях «вчера было надо» — это не про идеальную архитектуру и не про проценты покрытия. Это про сохранение управляемости системы, снижение рисков и поддержку скорости развития продукта в реальной промышленной среде. Легаси невозможно победить разом, но его можно сделать управляемым и безопасным для дальнейшей эволюции.

Комментарии0
Тоже интересно
Комментировать
Поделиться
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники