Тестирование #
Тесты - кусочки кода, проверяющие корректную функциональность вашего приложения, или его частей. Один такой кусочек называется тест кейсом, процесс их написания называется покрытием кода приложения тестами.
Тесты бывают различных видов, в зависимости от того, что они тестируют. Рассмотрим основные:
- Юнит тесты тестируют небольшие части кода, методы или классы. Типичный пример юнит теста - создать объект, вызвать его метод, проверить результат.
- Интеграционные тесты проверяют, что ваше приложение работает правильно в контексте внешних инструментов и сервисов, например, баз данных. Пример интеграционного теста - вызов метода REST API вашего приложения, проверка корректности результата.
- E2E (end to end) тесты тестируют приложение в целом, затрагивая максимальное количество его частей. Пример - на веб-интерфейсе приложения есть форма, при заполнении и отправки которой в базе появляется новая запись. E2E тест может сэмулировать действия на веб-интерфейсе, после чего проверить состояние базы данных.
Кроме видов тестов, важно понимать некоторые смежные с тестированием идеи:
- Mocking - техника эмуляции поведения какого-то метода или внешнего сервиса. Например, если метод возвращает какое-то постоянно меняющееся значение (биржевую котировку, например), то в целях предсказуемого теста можно создать мок объект, возвращающий заранее известную котировку, провести с ней некоторые вычисления и проверить результат на корректность.
- Edge case (пограничный случай) - маловероятный, но тем не менее возможный пример входных данных, который может получить тестируемый код. Пример - длина email при регистрации пользователя. Маловероятная, но максимально возможная длина email адреса - 320 символов, и тестируя пограничные случае мы можем быть уверены, что приложение корректно их обрабатывает.
- Тестовые данные - если код работает с данными, то для его тестирование нужны тестовые данные. Такие данные редко являются данными реальных пользователей (это было бы небезопасно), а их целью зачастую является воссоздание различных пограничных случаев.
- Тестовое окружение - во время тестов редко используется реальные база данных и внешние сервисы, это создавало бы ненужную активность (например, вставку тестовых данных в базу). Поэтому, частая практика - создать отдельное тестовое окружение, которое рождается перед стартом тестов и уничтожается после. Пример - вместо внешней Postgres базы данных, можно запустить in-memory H2 базу и инициализорвать её состояние таблицами с тестовыми данными. Другой популярный инструмент - Testcontainer, позволяет запускать необходимые для тест кейсов инструменты (базы данных, очереди) в Docker контейнерах.
В работе с тестами, как и везде, есть плюсы и минусы.
Плюсы:
- Написание тестов помогает формализовать работу приложения
- Для написания качественных тестов покрываемый ими код должен быть спроектирован на наобходимом уровне. Необходимость тестов может стать поводом для рефакторинга, улучшающего качество кода
- Тесты являются ещё одной формой документации, хочешь понять в деталях что делает класс - прочитай юнит тесты к нему
- Тесты помогают поддерживать работоспособность кода при его рефакторинге и добавления нового функционала. В случае некорректных изменений часть тестов сломается
- Тесты помогают поддерживать здоровый уровень качества кода приложения, особенно в больших командах, где люди приходят и уходят
Минусы:
- Дополнительная работа. Написание тестов и их поддержка требуют времени
- Плохо написанные тесты создают больше проблем, чем приносят пользы
Практически любой устоявшийся проект содержит тесты, и разработчикам необходимо уметь с ними работать. Уровень проникровения тестов в проект, их глубина и количество зависят от конкретных условий и варьируются от поверхностного тестирования до полного TDD.
Unit тестирование #
Для написания юнит тестов студент должен уметь писать качественные тест кейсы и пользоваться одним из популярных фреймворков для юнит тестирования (самый популярный - JUnit 5). Важнее всего понять идеи качественных кейсов, применять эти идеи к конкретной библиотеке - дело практики.
Основные рекоммендации для написания качественных юнит тестов:
- Проверяйте пограничные случаи
- Тестируйте не только успешные сценарии работы кода, но и неудачные - покрывайте тестами случаи, когда метод должен вернуть ошибку или кинуть exception
- Давайте тест кейсам короткие и понятные имена, описывающие суть их проверки. Если имя слишком длинное или непонятное, возможно, тест слишком общий или сложный
Что нужно знать о JUnit 5:
- Как добавить JUnit 5 в Maven проект и написать первый тест - https://www.baeldung.com/junit-5
- Аннотации JUnit
- Assertions
- Assumptions
Избранные курсы и учебные ресурсы #
- Курс “Продвинутая Java” Наиля Алишева, глава “JUnit”
- Плейлист по JUnit5 от dmdev. Тоже самое в виде курса - https://www.udemy.com/course/junit5-dmdev/
Интеграционные тесты #
Интеграционные тесты проверяют взаимодействия между частями системы (например - между слоем сервисов и слоем хранения данных) и взаимодействия с внешними сервисами. Для написания таких тестов нужно знать и уметь пользоваться следующими идеями и инструментами:
- Фреймворк для написания тестов - JUnit 5
- Моки, как инструмент симуляции поведения классов или внешних сервисов. Библиотека для создания моков - Mockito
- Тестовые данные, независимые от основных данных приложения. Например - in-memory H2 DB, создаваемая для прогона тестов, и уничтожаемая после
- Testcontainer - библиотека для запуска экземпляров нужных для тестов инструментов внутри Docker контейнеров
Примеры интеграционного тестирования в контексте бэкенд приложений:
- Взимодействия класса-сервиса и БД, куда сервис вставляет данные. Можно проверить реакцию БД на вставку некорректных данных и реакцию сервиса на возникшую при этом ошибку
- Взаимодействия класса-сервиса и внешнего REST API. Проверки парсинга ответов, реакции на HTTP ошибки (коды 4xx, 5xx) и сетевые ошибки (таймаут подключения)
- Взаимодействия REST контроллера и сервисов. Проверка того, что REST API вернёт ожидаемые ответы на различные наборы параметров в запросах. Реакции на ошибки - неправильно сформированные запросы, отсутствие необходимой авторизации
Избранные курсы и учебные ресурсы #
- Доклад по TestContainers с конференции Joker