что такое заглушки в тестировании

Тестируем интеграцию с внешними сервисами

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

В чем собственно проблема?

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

Описанные проблемы заставляют вас искать альтернативные решения и они существуют.

Заглушки правят миром тестирования!

На помощь вам могут придти разнообразные варианты заглушек (не нашел лучшего перевода термина mock objects). Есть несколько вариантов заглушек: mock, stub, dummy, spy, fake. Знать и различать их нужно и важно, поэтому стоит почитать и разобраться в специфике, но речь пойдет не об этом. Нам понадобится только один из видов заглушек, который наиболее подходит для работы с внешними сервисами — fake реализация.

Fake реализация представляет из себя упрощенный вариант настоящего сервиса, который работает полностью предсказуемо, локально, дает полный доступ к данным и настройкам, а также не требует никакой дополнительной работы в каждом тесте. Таким образом, мы сможем прозрачно заменить настоящий сервис в тестах на fake реализацию и решить все проблемы. Звучит просто? Не очень!

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

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

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

Я не готов к таким изменениям!

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

Кому-то даже этот набор мер позволит существенно улучшить свое тестирование.

Заключение

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

Источник

Тестирование в Яндексе. Сам себе web-service over SSH, или как сделать заглушку для целого сервиса

что такое заглушки в тестировании. Смотреть фото что такое заглушки в тестировании. Смотреть картинку что такое заглушки в тестировании. Картинка про что такое заглушки в тестировании. Фото что такое заглушки в тестировании

Думаю, каждый из вас при очередном релизе задавался вопросами: «Точно ли мы отсылаем верный запрос?» или «Точно ли мы передали все необходимые параметры этому сервису?». Всем должно быть известно и о существовании негативных сценариев развития событий наравне с позитивными. Это знание должно активно порождать вопросы из серии «Что если. ». Что если сервис станет обрабатывать соединения с задержкой в 2 часа? Что если сервис ответит абракадабру вместо данных в формате json?

О таких вещах нередко забывается в процессе разработки. Из-за сложности проверки проблем подобного рода, маловероятности таких ситуаций и еще по тысяче других причин. А ведь странная ошибка или падение приложения в ответственный момент могут навсегда отпугнуть пользователя, и он больше не вернётся к вашему продукту. Мы в Яндексе постоянно держим подобные вопросы в голове и стремимся максимально оптимизировать процесс тестирования, используя полезные идеи. О том, как мы сделали такие проверки легкими, наглядными, автоматическими и пойдет речь в этой статье.

Есть ряд давно известных способов узнать, как и что передается от сервиса к сервису — от мобильного приложения к серверу, от одной части к другой.
Первый из наиболее популярных и не требующих серьезной подготовки — подключиться специальной программой к одному из источников передачи или приёма данных. Такие программы называются анализаторами трафика или чаще — снифферами.
Второй — подменить искусственной реализацией целиком одну из сторон. В таком подходе есть возможность определить четкий сценарий поведения в определенных случаях и сохранять всю информацию, которая придет этому сервису. Такой подход называется использованием заглушек (mock-объектов). Мы рассмотрим оба.

Использование снифферов

Приходит новый релиз или отладка изменений, затрагивающих межсервисное общение. Мы вооружаемся нужными программами-перехватчиками — WireShark’ом или Tcpdump. Запускаем перехват трафика до нужного узла, наложив фильтры хоста, порта и интерфейса. Делаем «темные дела», инициируя нужное нам общение. Останавливаем перехват. Начинаем его разбирать. Процесс разбора у каждого сервиса свой, но обычно всегда напоминает судорожные поиски в куче текста заветных GET, POST, PUT и т.д. Нашли? Тогда повторяем это из релиза в релиз. Это же теперь проверка на регрессию! Не нашли? Повторяем это с разными комбинациями фильтров до понимания причин.

Из релиза в релиз?

Вручную такое делать можно раз. Или два. Ну, может быть, три. А потом точно надоест. А на пятый релиз это общение возьмет и сломается. Особенно сложно это заметить косвенно, когда общение представляет из себя вызов колбэка с каким-нибудь уведомлением. Повторяющиеся из релиза в релиз механические действия, отнимающие много времени и сил, стоит автоматизировать. Как это делать в JAVA? Уверен, на других языках это можно сделать похожим образом, но конкретно связка JUnit4 + Maven для автоматизации тестирования в Яндексе прекрасно работает и хорошо себя зарекомендовала.

Почему не нужно так делать?

Хочу заметить, что «не нужно» не значит «не можно».

Использование заглушек вместо web-сервисов

Так как речь идет о тестировании, то, скорее всего, у нас есть все возможности не просто поставить сеточку в виде сниффера, но и подменить один из сервисов целиком. При таком подходе до искусственного сервиса дойдут «чистые» запросы, а у нас будет возможность управлять поведением конечного пункта для сообщений. Для таких целей есть замечательная библиотека WireMock. Её код можно посмотреть на GitHub-странице проекта. Суть в том, что поднимается web-сервис с хорошим REST-api, который можно настроить почти любым образом. Это JAVA-библиотека, но у нее есть возможность запуска как самостоятельного приложения, было бы доступно jre. А дальше простая настройка с подробной документацией.

Тут и произвольные коды ответа, и произвольное содержимое, и прозрачное перенаправление запроса в реальные сервисы с возможностью сохранить ответы и отсылать их затем самостоятельно. Особо стоит отметить возможность воссоздать негативное поведение: таймауты, обрывы связи, невалидные ответы. Красота! Библиотека при этом может работать и как WAR, который можно загрузить в Jetty, Tomcat и т.д. И, самое главное, эту библиотеку можно использовать прямо в тестах как JUnit Rule! Она сама позаботится о разборе запроса, разделив тело, адрес, параметры и заголовки. Нам останется только в нужный момент достать список всех пришедших и удовлетворяющих критериям.

Автоматизируем проверки, используя заглушку

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

Схема

Поднимаем искусственный web-сервис

Как поднять сервис вручную, подробно описано на сайте wiremock в секции Running standalone. Как использовать в JUnit тоже впрочем описано. Но это нам понадобится в дальнейшем, поэтому приведу немножко кода.

Создаем JUnit правило, которое будет поднимать сервис на нужном порту при старте теста и завершать после окончания:

Начало теста будет выглядеть примерно так:

Здесь мы настраиваем поднятый web-сервис, чтобы он на любой запрошенный адрес отвечал кодом 200 с телом «ОК». После нехитрых действий по настройке, есть несколько вариантов развития событий. Первый — у нас нет никаких проблем с доступом на любой порт от клиента до той машины, на которой выполняется тест. В этом случае мы просто совершаем нужные действия в рамках тесткейса, после — переходим к валидации. Второй — у нас есть доступ только по ssh. Все же порты прикрыты брэндмауэром. Тут на помощь приходит ssh port forwarding (или ssh-tunneling). Об этом речь ниже.

Сокращаем дорогу пакетам

Если в двух словах, то ssh port forwarding (или ssh-tunneling) — это прокидывание трубы через ssh соединение от порта на удаленной машине до порта на локальной. Хорошую инструкцию по применению можно найти на www.debianadmin.com

Делаем junit-правило перенаправления портов

Вспоминаем про библиотеку Ganymed SSH2. Подключаем ее, используя maven:

(Релизную версию всегда можно увидеть в Maven Central.)

Само соединение должно выглядеть примерно так:

Валидируем

Успешно поймав запросы заглушенным сервисом, остается только проверить их. Самый простой способ — использовать встроенные средства WireMock:

Гораздо более гибкий способ — просто получить список нужных запросов, а потом, достав определенные параметры, применить к ним проверки:

Как это сработало в Яндексе

Всё сказанное выше — серьезный общий подход. Его можно использовать во множестве мест как целиком, так и по частям. Сейчас использование заглушек на интеграционном уровне отлично работает в целом ряде больших проектов для подмены различных функций сервисов. Например, у нас в Яндексе есть сервис загрузки файлов, который записывает информацию о файлах не самостоятельно, а еще через один сервис. Начали загружать файл — отослали запрос. Загрузили, посчитали контрольные суммы — еще один запрос. Проверили файл на вирусы, готовы с файлом работать дальше — еще один. Каждая следующая стадия продолжается в зависимости от ответа на предыдущие, при этом количество соединений между сервисами ограничено.

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

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

Проверив, что за 120 секунд при ожидании ответа на сервисе в 60 секунд пришло два запроса, мы точно убедились, что сервис загрузки файлов не зависнет в ответственный момент.

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

О чём еще стоит сказать

Локальное перенаправление портов

Источник

Что означает «заглушить» в программировании?

например, что это означает в этой цитате?

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

6 ответов

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

Внешняя Зависимость-Существующая Зависимость:
Это объект в вашей системе, который ваш код под тестом взаимодействует и над которым у вас нет контроля. (Общий примерами являются файловые системы, потоки, память, время и так далее.)

Например в приведенном ниже коде:

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

A заглушки, в этом контексте, означает макет реализации.

то есть простая, поддельная реализация, которая соответствует интерфейсу и должна использоваться для тестирования.

термины непрофессионала, это фиктивные данные (или поддельные данные, тестовые данные. так далее.) который можно использовать для тестирования или разработки кода до тех пор, пока вы (или другая сторона) не будете готовы представить/получить реальные данные. Это программистский «Lorem Ipsum».

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

самые известные виды заглушек очевидно для распределенного программирования, когда вызывать удаленные процедуры (RPC) или удаленные объекты (RMI, описание). Большинство распределенных программных фреймворков / библиотек автоматизируют генерацию заглушек, так что вам не нужно писать их вручную. Заглушки могут быть сгенерированы из определения интерфейса, написанного с помощью IDL например (но вы также можете использовать любой язык определения интерфейсов).

типично, в RPC, RMI, CORBA, и так далее, одно различает заглушки на стороне клиента, которые в основном заботятся о маршалинге / сериализации аргументов и выполнении удаленного вызова, и серверные стабы, которые в основном заботятся о unmarshaling / десериализации аргументов и фактически выполняют удаленную функцию/метод. Очевидно, что клиентские заглушки расположены на стороне клиента, в то время как заглушки sever (часто называемые скелетами) расположены на стороне сервера.

написание хороших эффективных и общих заглушек становится довольно сложным при работе со ссылками на объекты. Большинство фреймворков распределенных объектов, таких как RMI и CORBA, имеют дело со ссылками на распределенные объекты, но большинство программистов избегают этого, например, в средах REST. Как правило, в средах REST программисты JavaScript делают простые функции заглушки для инкапсуляции вызовов AJAX (сериализация объектов поддерживается JSON.parse и JSON.stringify ). The Swagger Codegen проект обеспечивает обширное поддержка автоматического создания заглушек REST на разных языках.

заглушка-это определение функции, которое имеет правильное имя функции, правильное количество параметров и выдает фиктивный результат правильного типа.

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

Источник

Мы не ищем баги: что такое нагрузочное тестирование

Как узнать, не превратится ли ваш интернет-магазин в тыкву во время «чёрной пятницы» — когда трафик вырастет в 10 раз.

что такое заглушки в тестировании. Смотреть фото что такое заглушки в тестировании. Смотреть картинку что такое заглушки в тестировании. Картинка про что такое заглушки в тестировании. Фото что такое заглушки в тестировании

что такое заглушки в тестировании. Смотреть фото что такое заглушки в тестировании. Смотреть картинку что такое заглушки в тестировании. Картинка про что такое заглушки в тестировании. Фото что такое заглушки в тестировании

Давид Нариманидзе

что такое заглушки в тестировании. Смотреть фото что такое заглушки в тестировании. Смотреть картинку что такое заглушки в тестировании. Картинка про что такое заглушки в тестировании. Фото что такое заглушки в тестировании

Taode01 в Twitter. 28 лет. Полтора года в нагрузочном тестировании, куда перекатился из системного администрирования и любительской разработки мобильных приложений. В абсолютном восторге от работы, потому что это редкая возможность спасать компанию от лишних трат, а клиентов — от расходования совсем не казённых нервов. Да ещё и практически неограниченно развиваться самому: во время работы в НТ приходится и код писать, и железо подбирать, и взаимодействовать с большим количеством клёвых специалистов из других отделов.

Нагрузочное тестирование (НТ) — один из тестов производительности. От любой системы требуется быстро и правильно отвечать на запросы пользователей: и если правильность ответов относится скорее к функциональному тестированию, скорость является как раз заботой специалистов по нагрузочному тестированию. Однако формулировка «система должна отвечать быстро» — слабое требование.

Мне нравится определение из блога Miro на «Хабре»: «Нагрузочное тестирование — это тип тестирования, в котором мы проверяем, соответствует ли наша система поставленным нефункциональным требованиям к производительности при работе под высокой нагрузкой в различных сценариях».

В основе статьи — Twitter-тред автора.

Какими бывают нагрузочные тесты

Начнём с того, какие бывают виды тестирования. У каждого инженера есть мнение на этот счёт, поэтому и я поделюсь своим 🙂 Я разделяю тесты на функциональные, нефункциональные и связанные с изменениями.

Функциональное тестирование. В него входит проверка безопасности и взаимодействия — мы испытываем систему и осознанно бьём по её слабым местам, убеждаемся, что она выполняет все функции, которые были прописаны в ТЗ.

Нефункциональное тестирование (НФ). Определяет характеристики ПО, которые измеряются в каких-то конкретных величинах. В первую очередь на таких тестах изучают производительность системы — проводят нагрузочное и стрессовое тестирование, исследуют стабильность и работу с большими базами данных. А после этого проверяют настройки, отказоустойчивость и восстановление системы, ищут способы увеличить её производительность. Тестирование производительности помогает узнать, как меняются стабильность и быстродействие системы под разной нагрузкой, а также проверить её масштабируемость, надёжность и уточнить, сколько ресурсов она будет использовать.

Вид НФ-тестаНа какие вопросы отвечает
Нагрузкавопросы отвечает»>Соответствует ли нефункциональным требованиям система
Стабильностьвопросы отвечает»>Надёжно ли работает система в течение продолжительного времени
Отказоустойчивостьвопросы отвечает»>Сможет ли система сама переместиться на другой сервер, если откажет основной
Восстановлениевопросы отвечает»>Как быстро система восстановится после сбоя
Стрессвопросы отвечает»>Что случится при незапланированной нагрузке
Объёмвопросы отвечает»>Как будет работать проект, если база данных вырастет в 100 раз
Масштабируемостьвопросы отвечает»>Как будет увеличиваться нагрузка на компоненты системы с ростом числа пользователей
Потенциалвопросы отвечает»>Сколько пользователей могут работать в системе одновременно
Конфигурациявопросы отвечает»>Как заставить систему работать быстрее
Сравнениевопросы отвечает»>Какое оборудование и ПО выбрать

Тесты, связанные с изменениями. К этой категории относятся:

Как составить методику нагрузочного тестирования

Методика нагрузочного тестирования (МНТ) — почти как Библия для нагрузочника. Это документ, в который необходимо вписать всё, что может случиться на проекте, учесть максимальное число сценариев и результаты тестов.

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

Я разрабатываю методику нагрузочного тестирования по такой структуре:

1. Информация о проекте и определения терминов.

2. Цели тестирования. Например, «внедрить в программу новую фичу» или «подготовить интернет-магазин к распродаже, когда пользователей на сайте будет в X раз больше».

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

У меня заглушки и эмуляторы работают на Java, скрипты я пишу в HP LoadRunner, а запускаю в Performance Center.

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

6. Раздел с описанием тестового стенда. Это схемы с серверами, заглушками и генераторами нагрузки.

7. Таблица с требованиями к железу.

8. Таблица отличий стенда от системы на продакшене.

9. Стратегия тестирования.

10. Описание видов тестирования.

11. Требования к производительности от заказчика.

12. Моделирование нагрузки.

13. Профиль (который мы получаем от аналитиков или собираем на основе бизнес-прогнозов).

15. Стоимость внезапного изменения требований к проекту. Это избавит исполнителя и заказчика от лишних забот.

16. Материалы для сдачи проекта, куда входит всё, что мы подготовили для следующего специалиста.

Зачем всё это?

Если заказчик ничего не знает о конкретном тестировании, методика ответит на все его вопросы. В ней объясняется, за что компания платит деньги подрядчику и какие результаты получит на выходе.

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

Стратегия заканчивается выводами и списком критериев успешного завершения НТ. В выводы включаются данные, которые мы получили в результате мониторинга, общее заключение и список успешно проведённых тестов.

Как проводят нагрузочное тестирование

Чтобы провести нагрузочные тесты новой системы, я использую такой чек-лист:

ПО для НТ

Для проведения нагрузочного тестирования необходимо специфическое ПО.

Я лично работаю с HP LoadRunner, ещё есть ПО Gatling, Apache JMeter, BlazeMeter, LoadNinja и даже отечественный «Яндекс.Танк». У каждого из них есть свои плюсы и минусы: одни не работают со специфическими протоколами, другие бесплатны, третьи больше дружат с тяжёлыми скриптами и так далее.

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

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

Выводы

обложка: кадр из фильма «Зомби по имени Шон»

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *