Рубрики
Без рубрики

Тестирование на основе поведения в корпоративных приложениях

Рассмотрим возможность уменьшения утечек ошибок в микросервисах, совместно используемых несколькими командами разработчиков… С тегами java, микросервисы, тестирование, архитектура.

Анализ сокращения утечек ошибок в микросервисах, совместно используемых несколькими командами разработчиков

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

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

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

Примером может служить пользователь, желающий узнать время доставки заказа, находясь на странице сведений о заказе. Чтобы сгенерировать ETA для доставки (согласно приведенной выше диаграмме), микросервису доставки потребуется получить заказ, хранящийся в службе управления заказами, сверить его местоположение со службами склада и логистики, получить информацию о водителе и оценить время доставки в зависимости от GPS-маркера. Это четыре разные подсистемы, работающие в унисон, чтобы заполнить ярлык на экране пользователя информацией о доставке заказа.

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

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

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

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

Но разве не для этого у нас есть интеграционные тесты?

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

Хотя у нас было более 80 % охвата во всех наших наборах модульных тестов, причина, по которой он больше похож на рожок мороженого, чем на пирамиду, заключалась в том, что мы добавили так много тестовых примеров интеграции и E2E, что к концу некоторые наборы интеграции заняли бы более 60 минут – это 1 час, потраченный разработчиком, ожидающим, не нарушит ли их изменение кода другую функцию в службе, — и с набором, запущенным на сервере CI, все равно будет сложно понять весь объем нарушенных тестов и сузить область влияния для отладки неисправной логики.

Мы разработали набор интеграционных тестов, который можно использовать для тестирования целых потоков API в микросервисе в сочетании с модульными тестами, которые будут выполняться автоматически вместе с набором модульных тестов. Тест будет выполняться из метода службы, который использует контроллер REST, при этом имитируя только вызовы внешней базы данных и API.

Как показано выше, мы только имитируем все, что находится вне контроля службы, т. е. базу данных (с использованием тестовых контейнеров) и внешние вызовы API (с использованием WireMock). В отличие от обычных интеграционных тестов, это позволяет нам утверждать не только объект ответа, отправленный из службы, но и состояние базы данных, а также запросы API, которые были отправлены в заглушки. Мы также можем настроить базу данных и заглушки для возврата различных результатов в службу, чтобы воссоздать успешные, ошибочные и резкие потоки, чтобы подтвердить правильное поведение в этих сценариях.

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

Соглашения об именовании

Именно здесь БДТ получил свое название. Помните, что вы тестируете полный поток с точки зрения нижестоящей службы. Тестовый пример для предыдущего примера, который возвращает ETA доставки заказа ( GET/order/:идентификатор заказа/местоположение ), где вам также необходимо имитировать сбой вышестоящей службы, будет выглядеть так, как показано ниже.

Здесь имя тестового случая должно отражать ожидания службы, которая будет использовать этот метод с помощью вызова API в соответствии с контрактом. Мы также стараемся убедиться, что название четко определяет область тестирования, чтобы разработчик мог просмотреть тестовый случай и сразу узнать, что ожидается.

Поскольку эти новые тесты выполняются вместе с существующими модульными тестами, а также поскольку база данных и внешние API—интерфейсы подвергаются насмешкам, мы увидели, что около 1500 тестовых случаев завершаются в течение нескольких минут – это примерно на 95 % быстрее, чем наш предыдущий набор интеграционных тестов, запущенный на сервере CI, в то время как более или менее охватывал те же тестовые случаи.

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

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

Отказ от ответственности : Стратегия тестирования, описанная здесь, не предназначена для замены модульных тестов.

Оригинал: “https://dev.to/damianperera/behaviour-driven-testing-in-enterprise-applications-59fa”