Как стать автором
Обновить

Комментарии 12

Тема очень хорошая и правильная. Частенько сам думаю об этом, когда ловлю себя на мысли что мои функциональные или интеграционные тесты дублируют модульные.


Например, есть форма с полями и хитрой валидацией. Валидация вынесена в отдельные методы. Я тестирую валидацию подробно, все кейсы которые приходят в голову.


Когда тестирую валидацию в форме — проверяю несколько кейсов (меньше чем в модульных), проверяю, что невалидную форму нельзя засабмитить, что тексты ошибок правильно отображаются, что валидную форму засабмитить можно, и, как правило, все.


А когда тестирую эту форму в связке с бизнес-логикой и IO — проверяю что ручка API вызывается с верными параметрами (засабмиченными из формы) если она валидна, и не вызывается — если невалидна.


Итого на какой-нибудь сценарий с пустым юзернеймом или емейлом без собачки может быть 3 разных теста (а еще в QA в e2e тестах может написать что-то подобное), которые вроде повторяются, но тестируют разное.


Внимание вопрос — а когда остановиться? Как поймать баланс? Какие из этих тавтологических тестов можно не писать и съэкономить на их написании, если они перекликаются? Понятно, что однозначного ответа нет, но буду признателен всем, кто поделится опытом.

то, что вы описываете, это не тавтологические тесты. Тавтологические тесты — это тесты, которые повторяют имплементацию.

Дублирование же интеграционных и юнит тестов решается тем, что при наличии хороших юнит тестов интеграционные перестают быть нужны. Т.е. вопрос — почему вообще требуется запускать форму с бизнес-логикой? Что в этом целом больше, чем отдельные части?
Наличие хороших юнит-тестов не отменяет пользу и существование интеграционных тестов.
Интеграционные тесты могут покрывать в том числе логику настройки окружения, логику сценариев деплоя, и т.д.

Приведите пример какой нибудь, трудно абстрактно обсуждать

А правильный ли урл указан в качестве точки подключения к БД?
А стартует ли вообще наш докер образ и сервис слушается на нужном порте?
И т.д.
Очевидно, это полезно проверять. Модульными тестами такое не проверить.

Насчёт урла я не понимаю. Урл — это внешний параметр, тестировать его бесполезно. Работающий дев урл ничего не говорит о QA или продакшене.


Про докер я не знаю, что вы конкретно имеете ввиду — если у нас приложение внутри докера, то он опять же внешний получается компонент.


Как проверять и тестировать конфигурации девопс пайплайнов — это вообще отдельный, параллельный набор практик и гайдов, включая соображения того порядка что урл базы может поменяться или быть недоступным, потому что айпи адрес на AWS отвалился, или докер не стартует внутри нашего контейнер сервиса потому что опять что нибудь. И это все не проверить интеграционными тестами, это иллюзия. Это PaaS, который курируется и верифицируется иначе

Если команда отвечает за сервис от начала до конца, в том числе за конфигурации, которые как все артефакты лежат в git-репозитарии и проходят обычный цикл разработки (планирование-реализация-тестирование-доставка), то да, появляются тесты на докер, урлы бд, и т.д.
если команда отвечает за сервис от начала до конца, это не значит, что нужно пренебрегать практиками. Cloud-native, 12-factor и тп
Интеграционные тесты приложения вместе с окружающей средой вредят и приложению, и окружающей среде. Индустрия в принципе движется туда, где эти вещи ортогональны.
Я в интеграционных тестах концентрируюсь на:
— happy path
— очень ограниченное количество fail case
Дальше из эксплуатации станет понятно, какие кейсы в интеграционные тесты добавить.

Тесты валидации, и вообще поведение выставленного API — проверяется в функциональных тестах. Но без деталей. Например для тестов валидации — проверяется что на конкретный запрос в результате инстацируется фабрикой конкретный валидатор и ему передается на валидацию конкретный объект. А все детали валидации тестируются в модульных тестах.

Но это в общем случае. Есть немало исключений.
Например, если валидаторы пишет одна команда. А использует их в конкретном сервисе, которые выставляет API, другая команда. Понятно, у первых могут быть свои тесты. Но вторым, чтобы быть уверенными в том, что все работает ожидаемым образом, могут быть свои тесты, реализованные на функциональном-интеграционном слое, которые могут повторять значительную часть логики тестов первой команды.

Я в интеграционных тестах концентрируюсь на:
— happy path
— очень ограниченное количество fail case
Дальше из эксплуатации станет понятно, какие кейсы в интеграционные тесты добавить.


Это знакомо, так девяносто процентов делает, т. е. фактически юзеры тестируют.


Тесты валидации, и вообще поведение выставленного API — проверяется в функциональных тестах. Но без деталей. Например для тестов валидации — проверяется что на конкретный запрос в результате инстацируется фабрикой конкретный валидатор и ему передается на валидацию конкретный объект. А все детали валидации тестируются в модульных тестах.


Это тоже знакомый подход — мы решили что будем экономить на тестах и поэтому тестировать только места со сложной логикой. Проблема этого подхода в том, что он inplementation driven. Сложный валидатор может быть следствием плохой разбивки на эндпойнты например. В этих случаях тестируемые места превращаются в логические чёрные дыры, насасывая все больше условий, а остальные части становятся номинальными.


Например, если валидаторы пишет одна команда. А использует их в конкретном сервисе, которые выставляет API, другая команда. Понятно, у первых могут быть свои тесты. Но вторым, чтобы быть уверенными в том, что все работает ожидаемым образом, могут быть свои тесты, реализованные на функциональном-интеграционном слое, которые могут повторять значительную часть логики тестов первой команды.


Если валидаторы пишет другая команда, то это означает, что у нас внешняя зависимость. Для тестирования внешней зависимости мы делаем интеграционный тест для зависимости, который берет внешний урл, это нормально и это единственный валидный кейс для интеграции. Но запускать систему целиком для этого необходимости нет.

Это знакомо, так девяносто процентов делает, т. е. фактически юзеры тестируют

Интересный вывод конечно ;)

мое имхо, задача интеграционных тестов в первую очередь проверить, что несколько компонент успешно связаны между собой, отсеивая ошибки инфраструктуры и конфигурации. И как минимум самый популярный кейс успешно выполняется. Т.е. базовая функциональность работает.
В зависимости от важности системы и прочих обстоятельств, объем и покрытие интеграционных тестов может вырасти.

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

Тоже интересный вывод…

Мой посыл был только в том, что тестируем то, что есть в текущей реализации.
Есть в веб-компоненте сериализация/десериализация — тестируем сериализацию/десериализацию. Отдана валидация в стороннюю компоненту — значит здесь тестируем что передача в валидацию происходит правильно. А непосредственно валидацию тестируем в проекте компоненты валидации. Это общий случай, условная норма. Бывает много частных с отклонением от нормы.
>> Мой посыл был только в том, что тестируем то, что есть в текущей реализации.

Этому я совершенно не противоречу. Свой код покрывается юнитами, внешние контракты контрактными тестами, то бишь тестами зависимостей.

Мне показалось, что у вас есть избирательность в том, что тестировать, и прошу прощения, если это не так.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории