9 подписчиков
Всем привет! Ещё одно ревью на книгу, которую упоминал: Владимир Хориков Принципы юнит-тестирования. https://habr.com/ru/company/piter/blog/528872/ Можно сказать уникальная книга про то, как писать юнит тесты. Я знаю таких всего две - эту и Шаблоны тестирования XUnit. Must read. Некоторые моменты можно обсуждать, но откровенных косяков или воды не нашёл. Что запомнилось.
1) разделение кода на четыре группы: бизнес-логика, контролёр в широком смысле этого слова как код, обрабатывающий входящие запросы, тривиальный код и переусложненный код, в котором есть и внешние зависимости и бизнес-логика. От последнего нужно избавляться через рефакторинг, сводя его к бизнес-логике или контроллерам. На бизнес-логику пишем модульные тесты, на контроллеры - интеграционные. На тривиальный код ничего не пишем)
2) не нужно писать отдельные тесты на каждой класс бизнес-логики, нужно тестировать процессы и стремиться к максимальному покрытию. Для бизнес-логики
3) использование минимум mock в модульных тестах, в идеальном случае их вообще не должно быть. Т.е идея в том, что классы бизнес-логики получают и возвращают DTO, которые можно создать в тесте без всяких mock
4) в случае интеграционных тестов mock нужно делать на неконтролируемые нами внешние зависимости, типа очередей, внешних АС, email транспорта. БД в случае если это не наша частная БД. Если же у нас микросервис со своей БД, которая обновляется вместе с приложением и внешние клиенты в нее не ходят - ее mock-ать не нужно, более того и заменять ее HBase тоже не нужно, т.к иначе мы не сможем полноценно оттестировать работу с БД, да и возникнут накладные расходы на поддержание двух версий скрипов. Это как раз то, где можно дискутировать, но милая мне нравится.
5) чем меньше в приложении слоёв, тем лучше, проще тестировать
6) логирование может являться контрактом, например по требованию сопровождения или если на его основе работает мониторинг, тогда его тоже нужно mock-ать и тестировать.
7) организовать отправку событий, например, логирования, сообщений в Kafka или SMTP можно через стандартизацию механизма событий в доменной модели и обработку событий в слое «контроллеров».
8) если вернутся к модели тестов AAA - Arrange, Act, Assert, то Arrange и Assert в одном тесте может быть много, а вот Act должен быть один, иначе у нас проблемы с нашим Java API. Исключение - интеграционные тесты где сложно поднять контекст.
9) методы с инициализацией тестов типа @Before плохи тем, что сложно читать текст, т.к часть Assert в другом методе. Поэтому лучше использовать отдельные говорящие private/protected методы с параметрами, чтобы можно было настроить тестовые данные под каждый тест
10) название тестового метода должно читаться как фраза, разделять можно подчёркиваниями в случае Java, фраза не обязательно должна быть шаблонной как в BDD, краткость более важна. Кстати, в Kotlin слова в названии теста можно разделять пробелами.
11) интеграционные тесты дают хорошее покрытие, за счёт этого увеличивают защиту от ошибок в коде. Поэтому их лучше всего писать на позитивные сценарии, покрывающие максимум кода и те негативные сценарии, которые не удалось покрыть юнит тестами
12) антихрупкость тестов, о которой я уже писал, становится особенно важна по мере развития проекта. Т.е после некоторого времени более важно, чтобы тесты были антихрупкими, чем чтобы они находили все потенциальные ошибки. Т.к для последнего есть QA и приёмочные тесты
Я перечислил лишь то, что запомнилось, интересным идеей в книге намного больше. Интересных и практических. Повторюсь - must read!
#books #unittests
2 минуты
9 декабря 2022