Как ускорить долгие тесты в проекте и какие подходы использовать?
Что проверяют
Здесь речь обычно об интеграционных и сквозных тестах, где время уходит на базу, внешние сервисы и ожидания. Интервьюер хочет услышать, что вы ищете узкое место замером и понимаете цену каждого ускорения. Следом спрашивают, чем вы рискуете, заменив реальную базу на H2.
Как отвечать
Порядок такой: измерить, разложить тесты по уровням, потом ускорять самые дорогие.
- пирамида: проверку ветвлений бизнес-логики переносят в юнит-тесты, а интеграционным оставляют стыки: SQL, сериализацию, конфигурацию. Один интеграционный тест на сценарий вместо десяти на каждый вариант входа;
- Testcontainers: один контейнер на весь прогон (паттерн singleton container в базовом классе) вместо нового на каждый класс. Локально можно включить переиспользование через
.withReuse(true)иtestcontainers.reuse.enable=true, в CI его обычно не включают; - данные: схему накатывают один раз, а между тестами откатывают транзакцию или делают
TRUNCATE, а не пересоздают базу. Дорогую подготовку выносят в@BeforeAll; - Spring-контекст: единая конфигурация для интеграционных тестов, чтобы работал кэш контекста, и никаких лишних
@DirtiesContext; - внешние сервисы: WireMock или MockServer вместо реальных HTTP-зависимостей, контрактные тесты вместо сквозного прогона через три системы;
- ожидания: Awaitility с опросом условия вместо
Thread.sleep(5000); - CI: быстрые юнит-тесты на каждый коммит, интеграционные отдельной стадией, шардинг по нескольким агентам.
Стоит назвать и компромисс: быстрый тест, который перестал ловить реальные ошибки, хуже медленного.
Где спотыкаются
Меняют PostgreSQL на H2 ради скорости. Тесты ускоряются, но диалект, типы, блокировки и расширения ведут себя иначе, и ошибки всплывают только на проде.
Мокают всё подряд, вплоть до базы в тестах репозиториев. Набор становится быстрым и бесполезным.
Называют TDD или BDD способом ускорить тесты. Это практики написания тестов, на время прогона они не влияют.