Тесты на одном уровне абстракции
Май 2018
Практически любой программист знает, что интерфейс не должен зависеть от реализации. Это утверждение верно и в случае написания тестов. Но почему-то часто приходится видеть вот такое:
- создать пользователя 1 и пользователя 2 через методы, которые работают с базой данных
- добавить пользователя 1 в друзья к пользователю 2 через методы бизнес-логики
- запросить список друзей пользователя 2 с помощью HTTP-запроса
- проверить вхождения данных о пользователе 1 в полученном списке
- удалить пользователя 1 и пользователя 2 с помощью метода, который работает с базой данных
Это хрупкий тест, который может упасть из-за рефакторинга. Переименовали метод работы с БД – тест упал. Изменили интерфейс метода бизнес-логики по добавлению пользователя в друзья – тест упал. Ни одно из этих изменений не касалось HTTP-API, но тесты на HTTP-API начали падать. Столкнулись с таким поведением в своём проекте – значит пора перестать смешивать.
Не смешивать – это красиво
При написании теста нужно всегда находиться на одном уровне абстракции. В нашем случае, setup, action, assert и teardown должны использовать интерфейс HTTP:
- создать пользователя 1 и пользователя 2 через с помощью HTTP-запроса
- добавить пользователя 1 в друзья к пользователю 2 с помощью HTTP-запроса
- запросить список друзей пользователя 2 с помощью HTTP-запроса
- проверить вхождения данных о пользователе 1 в полученном списке
- удалить пользователя 1 и пользователя 2 с помощью HTTP-запроса
Такой тест будет стабильным все время, пока стабильно HTTP-API. Переписали весь сервис, но не меняли HTTP-API – тест будет проходить как раньше. А еще его легко понимать и воспроизводить вручную, потому что понятно, где проходит граница. Когда пишите тест, представляйте себе стакан с несмешивающимися жидкостями. Реально помогает.