В пирамиде тестирования End-to-End (E2E) тесты занимают одну из верхних ступеней. Написав один E2E тест, можно быть уверенным в результатах работы логики приложения, проверить интеграции с другими системами и создать "контракт" для вашего приложения.
К сожалению, многие из коллег, с которыми я работал, не писали E2E тесты. Отчасти потому что с головой ушли в модульное тестирование и посчитали, что оно лучше по ряду причин, включая моду на TDD. Отчасти потому что верили, что E2E тесты сложно писать, они долго исполняются, да и с инструментарием есть проблемы.
Разберемся с этими мнениями и посмотрим на плюсы, которые предлагает E2E тестирование.
Терминология
Под E2E тестами положим вид автотестов. Эти автотесты должны покрывать все функции сервиса с точки зрения клиента. Добиваются они этого, симулируя реальное взаимодействие клиента, будь это HTTP-запрос или нажатие на кнопку в UI.
Подход модульного тестирования лучше
Написание модульных тестов, по моему опыту, занимает куда больше времени, чем E2E тестов. Да, на первых порах придется разобраться как E2E тесты лучше писать, но ведь то же было верно и для модульных тестов.
Зато, в результате один E2E тест покрывает больше кода, чем один Unit-тест, хотя может занимать меньшее количество строк по сравнению с аналогичным модульным test suite.
Можно не тратить время на понимание того, как правильно мокировать зависимости, ведь ими становятся в E2E тестах внешние системы, а взаимодействие с тестируемым сервисом строится по принципу "черного ящика".
Не нужно проверять все граничные условия для отдельного метода класса. Это повышает гибкость работы с кодом, так как нет необходимости рефакторить весь test suite при малейшем изменении внутренней логики работы приложения.
Невозможно попасть в ситуацию, когда ты боишься выкинуть старый код, потому что придется пройтись по набору из 100 модульных тестов (написанных даже не тобой), которые так или иначе были завязаны на этот код.
Инструментарий и скорость прогона тестов
На сегодняшний день большинство backend-разработчиков пишут сервисы, представляющие API с помощью HTTP (возможно GraphQL) или некоторым подобием MQ. В таком случае достаточно обычного клиента HTTP, доступного в большинстве mainstream ЯП.
Frontend-разработчики пишут, в основном, для Web-платформ (браузеров) или для мобильных в виде нативных приложений. Тут ситуация немного сложнее, так как инструментарий требует более детального изучения, но не дольше любого остального инструмента, с которым Вам придется столкнуться при разработке приложений.
E2E тесты действительно требуют в среднем больше времени для прогона, нежели модульные. При этом они завязаны на скорость работы Вашей системы. Т.е. они становятся метрикой производительности отдельных операций. При необходимости, они могут просто преобразовываться в нагрузочные тесты.
Дополнительные плюсы E2E тестирования
Каждый отдельный тест покрывает реальный сценарий использования приложения и дает куда больше понимания другим разработчикам, в том числе и будущим, как именно и зачем все это работает.
По результатам работы Вы получаете "настоящий" code-coverage. Если есть код и его невозможно исполнить, выполняя клиентские запросы в реальном окружении, то, скорее всего, это лишний код. Если он проверяет граничные условия или ловит маловероятный exception, задумайтесь, возможны ли такие условия в принципе?
В целом, использование только E2E тестирования для приложения заставляет задуматься об упрощении структуры Вашей системы и улучшения документации.
E2E тесты могут использоваться как контракты API и взаимодействия с Вашим сервисом. К примеру, для backend, как только Ваш E2E тест меняется, необходимо убедиться, что frontend будет готов к таким изменениям.
Заключение
В целом, на мой взгляд, E2E тестирование предоставляет большие гарантии корректной работы системы, чем unit-тесты, большую гибкость в работе с кодом с точки зрения рефакторинга и отражает реальную суть работы приложения.
Спасибо Вам за внимание! А как Вы считаете, можно ли использовать только E2E тесты?