Обновить
7
1
Леонид Сухин@leva1981

Java разработчик

Отправить сообщение

Я был в такой ситуации и с Zonky, он же EmbeddedPostgres, Embedded... работал.

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

По покрытию. Посмотрите пожалуйста ответ на коммент выше, там где много букв. Я не предлагаю все методы покрывать интеграционниками. Достаточно happy path по всем сутевым кейсам. Юнит-тесты никто не отменял, через них прекрасно тестируется бизнес логика, если она не содержит зависимостей (DDD, утильные классы и библиотеки, просто отдельные методы с вынесенной в них логикой, ветвления с exception для повышения покрытия по параметру branch). Веду к тому, что и интеграционных тестов и юнитов должно быть ровно столько сколько нужно, чтобы покрыть все, что реально надо покрыть и что-бы эта история была устойчива к рефакторингу, насколько это возможно.

Ок, давайте подискутируем. У Хорикова описывается довольно много различных подходов, а также их плюсы и минусы. Как мне показалось, одна из ключевых мыслей Хорикова - что необходимо уйти от хрупких тестов Лондонской школы, когда мокается все и вся и по возможности использовать тесты, которую тестируют ваше приложение по принципу "черного ящика" и тестируют не классы, а определенный функционал. Но повторюсь - в книге разобрано много кейсов и мой ключевой вывод это только мой вывод.

Я не ставил себе целью показать все подходы, описанные у Хорикова. Я упомянул его книгу потому что а) она реально очень крутая и б) в ней основная мысль про то, что тестировать "черный ящик" гораздо лучше, чем "белый ящик", если можно так выразиться.

Основная цель статьи - научить людей пользоваться тест-контейнерами и сделать это быстро. Из моего опыта чтения других туториалов - как правило все требуется дорабатывать напильником, часто очень и очень много, моя же цель была дать реально production-ready инструмент, чтобы можно было сосредоточиться на тестах, а не мудохаться неделю с первичной настройкой.

Теперь про подход.

Пишем интеграционные тесты на все happy path. С поднятием инфры через тест-контейнеры и так далее. Так ты точно знаешь, что все связки отрабатывают насквозь, по крайней мере по одному положительному сценарию. Это кстати уже обычно дает примерно 65-70% покрытия кода.

Затем по мере возможности ты выносишь бизнес-логику в отдельные методы. Цель - метод без внешних зависимостей, без внешних сервисов. Такие методы от и до тестируешь через юнит-тесты. Подобные тесты неплохо пишет ИИ, с обработкой кучи корнер-кейсов (только за ИИ обязательно все надо перепроверить). Таким образом прекрасно тестируется вся логика, если вам повезло практиковать DDD-подход. То есть если у тебя есть бизнес-логика без зависимостей, то ее все так же тестируем через юниты. Это очень годно работает для всяких библиотек, которые что-нибудь считают, или там регулярками обрабатывают. Там прямо юниты рулят.

Что касается тестирования простых объектов. Этого нет в докладе и коде, но да, объекты типа dto, репозитории и тому подобное необходимо вообще исключать из анализа тестового покрытия, включать их в исключения JaCoCo/Сонара. Это не вошло в реализацию и в доклад.

Что касается "прикручиваете прорву моков, которые на запросы к базе возвращают кучу данных и на методы сохранения в базу прикручиваете моки, которые проверяют, что вы пытаетесь сохранить а базу. Еще и пытаетесь наверное, протестировать, как sql-ки формируются." Тут уж извините, но вам стоит повнимательнее еще раз прочитать доклад и посмотреть код. В том то и дело, что я не прикручиваю моки. Я поднимаю реальную инфру, которая нужна для функционирования сервиса. Реальный Пострес, реальную Кафку, реальный Редис (тут его нет) и так далее. И потом тестирую максимально реальное поведение сервиса. Мне не надо тестировать "sql-ки формируются" потому что я тестирую конечный результат. Дал на вход определенные параметры, в рест или кафку, и жду определенного результата - появления/изменения данных в базе, исходящего сообщения в очередь, вызова внешнего сервиса... Исходя из того, что вы пишите, создается впечатление, что как в анекоде из СССР - "Пастернака не читал. Но осуждаю". Так же и вы невнимательно по диагонали прочитали статью и судя по всему не удосужились посмотреть код. Пожалуйста, дайте статье и коду второй шанс - приглядитесь. Возможно, вы в итоге до конца не согласитесь с моим подходом и реализацией, но совершенно точно ваша критика будет другой.

Возможно вы слишком категоричны. Можете развернуть комментарий?

По первому вопросу - у меня мало опыта "натравливания" LLM на репозитории)) Наверно наличие фрагментов кода под комментами (ИЛИ-ИЛИ) действительно может создать некоторые затруднения. Но мне реально не хотелось делать две разные ветки, которые бы отличались буквально четырьмя строками кода и наличием/отсутствием одного-двух файлов. Я оставил все в одной куче специально, чтобы было сразу видно в чем собственно отличия. Наверно есть смысл форкнуть, удалить лишнее и уже после этого натравить LLM.

По второму вопросу - можно использовать в любых проектах.

Спасибо за статью. Подскажите пожалуйста, с каким минимальным железом стоит заходить?

Иван, браво! Потрясающая статья!

Норм, понял. Правки внес, спасибо! Текст не переведенный, писал сам. Но этот момент пропустил.

Не соображу, о чем речь. Возможно ошибаюсь, но Formatter это про преобразование только в одну сторону.

Информация

В рейтинге
1 508-й
Откуда
Рязань, Рязанская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Разработчик приложений
Средний
От 100 000 ₽
Java
Spring Boot
Java Spring Framework
Hibernate
PostgreSQL
REST
Junit
SQL
Git
Docker