Обновить

Black-box тесты на Java: функциональные тесты за секунды и в параллель и почему я остался на своих

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели5.2K
Всего голосов 2: ↑1 и ↓1+2
Комментарии7

Комментарии 7

В критериях про "Скорость" сказано, что у классики (SpringBootTest) минуты, тогда как у BlackBox - секунды. Это как? Само приложение такое тяжеловесное, что ему нужна пара минут? Тогда в докере будет так же. Или это зависимости поднять так много занимает? Тогда в docker compose поднять тестовые базы тоже будет так же.

Старт приложения и поднятие зависимостей это разовая штука, в обоих подходах одинаковая

Дело не в тяжести приложения. В классике контекст Spring часто перетряхивается прямо посреди прогона: разные конфигурации тестов, @MockBean, @DirtiesContext и приложение поднимается заново по нескольку раз за сюит. А JUnit всё это обычно гоняет в один поток, так что переподнятия складываются в те самые «минуты»

В BlackBox тесты идут параллельно: сервис поднят один раз, и тесты молотят его по HTTP пачкой одновременно, как обычные внешние клиенты. Им не нужен общий Spring-контекст, нечему мешать друг другу , поэтому распараллеливание честное и почти линейное отсюда и секунды. В классике так не разогнаться: общий контекст и общая БД заставляют тесты толкаться и сваливаться в последовательный прогон

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

 В классике так не разогнаться: общий контекст и общая БД заставляют тесты толкаться и сваливаться в последовательный прогон

Общая БД будет и для blackbox тестов, иначе я не понимаю, как именно работает ваше приложение, поднятое в blackbox, или оно там несколько реплик поднимает.

В общем, IMHO, для перехода на blackbox могут быть мотивы, но никогда не скорость, потому что поднять инстанс для блэкбокса на моей практике будет гораздо тяжелей, чем SpringBootTest, если последний правильно оформлять.

Согласен почти со всем это и есть мысль статьи

Единый контекст в Spring делается: один @SpringBootTestконфиг на всех, запрет @MockBean/@DirtiesContext, мок на HTTP-границе. Тогда приложение поднимается один раз и в классике старт перестаёт быть статьей расхода

И БД у black-box общая, вы правы: один сервис + одна база, никаких реплик. Просто её не чистят между тестами и изоляция по уникальному testRunId в данных, а не через TRUNCATE. И вся разница в скорости отсюда: она не от HTTP-границы, а от параллельности. Классика гоняется в один поток, потому что тесты дерутся за общее состояние и чистят таблицы; убрали очистку, ушли в уникальные ID и общую базу можно молотить потоками одновременно

Так что скорость не свойство black-box как такового, а связки «один контекст + параллель + изоляция по ID», и она прекрасно воспроизводится в обычных Spring-тестах

Что еще black-box даёт сверху и что в классике приходится держать на дисциплине он по построению запрещает лезть в кишки: нет инжекта бинов/DAO, и команда физически не может срастить тест с внутренностями в обход HTTP-границы. Она даже не знает что там за стек. В @SpringBootTest это держится только на договорённости

Продвигать опереденный тип пирамиды в отрыве от архитектуры это конечно жесть. Наезд на юниты тоже какой-то детский, их выхлоп напрямую зависит от уровня владения моками и качества самого кода.

Так в этом и весь тезис. Если польза теста зависит от того, насколько виртуозно я накрутил моки, тест проверяет мою сборку моков, а не поведение системы. Чем лучше я «владею моками», тем точнее я фиксирую текущую реализацию и тем громче всё краснеет на первом же рефакторинге без единого изменения поведения. Это не аргумент за юниты, это диагноз))

Про «пирамиду в отрыве от архитектуры» перечитайте концовку: я как раз не перешёл на black-box и не предлагаю всем переписываться. Я забрал одну дисциплину - тест как клиент. Это не про форму пирамиды, это про то, к чему тест прилеплен: к контракту или к потрохам. Архитектура тут не контраргумент, а ровно та причина по которой моки и оказываются хрупкими

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации