Использование mock при интеграции с внешним API

28.05.21

Разработка - Тестирование QA

На Infostart Meetup DevOps инженер-программист Андрей Крапивин поделился с коллегами опытом тестирования интеграции с внешним API – показал возможности мокирования и рассмотрел их применение на реальном примере тестирования погодного виджета для конфигурации «Бухгалтерия 3.0».

Тестирование интеграции с API

 

 

Задача интеграции с API встречается очень часто, по популярности она уступает только обмену между базами и выгрузке из Excel.

Есть много разных вариантов API:

  • Есть мастодонты – Google, Яндекс – у них много разных сервисов, с которыми можно интегрироваться. Например, получение переводов, генерация и чтение текстов, прогнозы погоды.

  • Часто приходится интегрироваться с «Почтой России» или OZON.RU – если ваша компания занимается перевозками или отправкой товаров.

  • С Telegram – если надо отправлять или получать данные и писать ботов.

  • И, конечно, наши государственные сервисы: например, ФНС, если вам нужно получать данные о контрагентах.

У всех этих вариантов есть нечто общее:

  • Клиент-серверное взаимодействие, когда вы от себя отправляете данные, а все обрабатывается на стороне сервиса.

  • Сервер не будет хранить ваше состояние – ему без разницы, какой вы запрос отправите, состояние запроса вы должны соблюдать самостоятельно.

  • Используется немного кэширования.

  • Формат ответа – обычно HTML, XML, JSON либо бинарные файлы (если вы что-то получаете в виде картинок или pdf-документов).

 

Проблемы тестирования

 

 

Какие проблемы возникают в тестировании с API?

  • Основное – стабильность тестов, потому что когда у вас внешнее API – вы целиком и полностью зависите от того, что происходит на сервере. Сервис может уйти на обслуживание, не выдержать нагрузки и, соответственно, ваши тесты тоже перестают проходить.

  • Возможность покрытия сценариев. Тяжело реализовать все сценарии, которые вы можете придумать, когда у вас внешнее API.

  • Большая проблема – скорость ответов. Зависит от того, какая нагрузка на сервере, которым вы пользуетесь, сколько до вас идет ответ.

  • Следующая проблема – риск работы с реальными данными. Если вы тестируете наживую, то можете пересечься с вашими реальными данными, которыми оперирует учетная система. Ничем хорошим это не закончится.

  • Еще есть проблема: можно увлечься, и вместо того, чтобы тестировать, как ваше приложение взаимодействует с API, начать тестировать API. Вы думаете: «А что будет, если я отправлю такой запрос, а если такой, а если здесь пробел поставлю?» И получается, что вместо того, чтобы придумать сценарий, как вы будете взаимодействовать с сервером, вы смотрите, как ответит сервер.

 

Методы решения проблем

 

Какие есть методы решения проблем?

 

 

Самый простой вариант – вам предоставят тестовый стенд. Вам выделяют отдельную область, в которой вы будете тестировать свои алгоритмы.

В чем тут может быть проблема? Если стенд один, а разработчиков несколько – ваши тесты могут мешать друг другу.

 

 

Следующий вариант – написать свой сервер.

Все программисты, если что-то не работает на стороне, начинают писать свое. Делаем небольшой сервер – берем Python или OneScript.Web – и пишем небольшие заглушки. Мы знаем, какие запросы отправляем, готовим под них ответы.

В чем здесь проблема? Его надо писать. Это будет ваше отдельное приложение, которое надо поддерживать.

 

 

Следующий вариант – использовать специальные mock-сервера (заглушки).

Для них все равно нужно будет готовить данные.

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

Mock-сервер можно использовать только для тестов. Никаких альфа-бета-тестирований на mock-сервере проводить не стоит – для этого нужно использовать только боевой контур.

 

 

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

Мы разберем мокирование.

 

Мокирование

 

Мокирование от английского mock – «заглушка». Выглядит это следующим образом.

 

 

Запускается тест.

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

  • Далее тест обращается к вашей системе, чтобы она отправила запросы не на реальный сервер, а на заглушку.

  • Заглушка присылает ответы, а тест верифицирует: правильные ли данные получила система.

 

 

Вариантов таких мок-серверов много, перечислю самые популярные.

  • Один из первых, который мне попадался – это Postman, в нем есть возможность мокирования. Postman – одно из мастхэв-решений, если вы пишете интеграцию. Работать с запросами в нем очень удобно. И также в нем есть собственная возможность мокирования. Достаточно слабенькая, но есть.

  • SoapUI – достаточно мощное решение, там есть запись ваших запросов, их воспроизведение, упаковка в сценарии. Достаточно популярное решение для мокирования.

  • Еще есть сервис WireMock.

  • Есть сервис МоckServer. С ним я еще не разобрался, он достаточно сложный.

  • И есть JSON-Server – легкое решение, в нем есть база данных, основанная на JSON. Он умеет сохранять данные и преобразовывать.

Но я вам хочу рассказать про работу с WireMock.

 

WireMock – запуск, возможности, управление

 

 

Что такое WireMock?

  • WireMock – приложение на Java, что уже хорошо. Значит, вы сможете его запускать и на Windows, и на Linux.

  • Он умеет работать в режиме JUnit, когда вы пишете тесты на Java, и Standalone – как отдельно запускаемое приложение. С 1С я его чаще использую как Standalone.

  • Он очень хорошо управляется через HTTP-запросы. Когда вы его как Standalone подняли, он управляется, отправляя запросы на нужный адрес.

  • Все настройки он хранит в JSON-формате – это очень удобно, потому что JSON хорошочитаемый, его удобно смотреть при code-review.

  • У него есть функция записи и воспроизведения – чуть позже расскажу, что это такое.

  • Также он умеет назначать приоритеты шаблонам, умеет работать с состояниями и симулировать ошибки.

Чтобы было понятнее – давайте разберем конкретную задачу.

 

Практика

 

 

Наша задача – сделать погодный виджет для Бухгалтерии 3.0. Я достаточно часто встречал такие обработки на Инфостарте – видимо, многие клиенты хотят знать погоду, не выходя из 1С.

Мы выведем на главной странице Бухгалтерии 3.0 текущий прогноз погоды и постараемся максимально закрыть это тестами.

Реализация выглядит вот так – это расширение, которое я нашел на Инфостарте в публикации //infostart.ru/public/801039/. Оно выводит погоду – сейчас +18 градусов.

Давайте накроем его код тестом.

Тест делаем как обычно, кнопконажималкой – запускаем 1С, получаем нужный элемент и проверяем его данные.

Насколько это будет стабильный тест? С утра у нас было +7, днем стало +15, два часа назад пошел дождь, но теперь светит солнце. Соответственно, тест будет совершенно нестабилен – каждый раз, когда меняется погода, тест будет падать.

Как раз его мы и попробуем замокировать.

 

Подготовка

 

Первым делом, нужно провести подготовку.

  • Настроить запуск 1С в режиме тестирования.

  • Научиться перенаправлять запросы – чтобы запросы отправлялись не к внешнему сервису, а к нашему.

  • Подготовить набор ответов.

Начнем с запуска в режиме тестирования. Я обычно реализую такой метод через параметр сеанса, который зависит от параметра запуска.

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

Теперь насчет подготовки мокированных ответов.

У WireMock есть специальноеприложение – WireMockUI, которое позволяет настроить следующую вещь: мы в нем указываем, какой сервис API мы хотим мокировать, на какой сервер мы его перенаправляем.

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

Вот так это выглядит. Мы включили запись, что-то потыкали, получили нужные ответы, забираем эти результаты себе. Складываем это в какую-то папку с проектом или еще куда. И после этого запускаем WireMock с указанием того, что все наши шаблоны лежат в нужной папке.

Шаблон выглядит вот так: здесь URL запроса и ответ.

Содержание большого JSON-ответа можно упаковать в отдельный файлик – его адрес будет указан в свойства bodyFileName.

Вот так выглядит этот JSON-файл ответа.

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

 

Макеты

 

Давайте подробнее разберемся, что такое макет.

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

Самое первое, что есть в шаблонах – какой HTTP-метод мы используем.

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

Дальше мы разбираем, куда уходит наш запрос.

  • Первый вариант – использовать свойство url, которое описывает полное соответствие, включая все параметры. Мы прямо говорим, что если мы делаем GET-запрос по такому-то URL – возвращай ответ. Это не очень удобно, потому что в коде могут поменяться местами параметры, некоторые параметры будут являться обязательными или необязательными.

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

  • И совсем простой вариант – с помощью свойства urlPath указывать только начальный путь. Чаще всего я использую именно этот вариант, когда указываю, что запрос будет по такому-то URL, а потом отдельно обрабатываю параметры запроса через свойство queryParameters.

Есть несколько вариантов обработки параметров:

  • equalTo – это точное соответствие, когда вы говорите, чему должен быть равен этот параметр;

  • matches – регулярное выражение, которому этот параметр должен соответствовать.

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

С помощью свойства bodyPatterns есть возможность обрабатывать тело запроса. В зависимости от того, какой запрос вы обрабатываете, можно использовать:

  • XPath-язык – свойство matchesXPath;

  • JSONPath – свойство matchesJsonPath;

  • или описывать полное совпадение тела запроса через свойства equalToXml и equalToJson.

Это все, что касается шаблона запроса.

Дальше этот шаблон переадресовывает к шаблонам ответа. То есть, для каждого шаблона на запрос мы готовим ответ.

Вы можете готовить динамические ответы:

  • указывать дату в определенном формате;

  • разбирать входящие параметры, если это требуется;

  • там есть конкатенация строк и т.д.

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

 

Stateful

 

Разберемся, что делать, если у нас есть зависимость от состояния. Сервер не хранит состояния обмена по API, но бэкэнд может какие-то состояния хранить.

Например, если у вас сервис учитывает контроль остатков. Вы делаете запрос остатков, списываете товар, делаете еще один запрос – у вас товар должен закончиться. Получается, у вас есть несколько состояний.

WireMock позволяет это реализовать:

  • у него есть понятие сценария;

  • каждый сценарий должен находиться в определенной стадии;

  • эти стадии можно переключать как прямым запросом по HTTP, так и самим сценарием.

Например, здесь на слайде указан сценарий «To do list», и текущее состояние у него стартовое (“requiredScenarioState”: “Started”).

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

Нам потребуется два шаблона:

  • один стартовый (“requiredScenarioState”: “Started”),

  • другой я назвал bad (“requiredScenarioState”: “bad”) – сейчас объясню, почему.

Логика такая – когда наш сервер стартует, он находится в стартовом состоянии и подает нужный ответ.

А когда мы переключим его в новое состояние, данные на виджете должны измениться.

Как это будет выглядеть в тесте? Мы указываем, что работаем со сценарием Weather.

Прямо в коде явно переключаем его состояние – тогда через 30 секунд у нас меняется погода на виджете.

 

Аварийные ситуации – низкая скорость, обрыв, мусор

 

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

Лучше постараться обработать эти аварийные ситуации – повторно отправить запрос или подсказать пользователю.

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

Как это можно реализовать с помощью мокирования?

Первое – задержка ответа. Прямо в шаблоне можно указать, что нам потребуется какая-то задержка.

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

  • Есть вариант показать, что это уже случайная величина на каждый запрос.

  • И есть интересный вариант – цепочка ответов, когда ваш запрос идет с задержкой в 1000 миллисекунд пятью пачками (каждые 200 миллисекунд отправляет пачку ответов) и в конце концов собирается. На слайде показано, как это может быть реализовано.

Еще интересный вариант, что делать, если вам пришел вообще невалидный ответ сервера:

  • вам может прийти пустой запрос;

  • может прийти мусор в ответе – когда вначале был json, а потом абракадабра;

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

На слайде показано, как выглядит запрос Postman, когда приходит совсем пустой ответ – он не может ничего прочитать.

Если вы перехватите такую ошибку, 1С это более-менее переваривает.

 

Интересный вариант реализации – как протестировать обрыв связи. Реализуется как раз цепочками состояний.

  • есть стартовое состояние – Started;

  • дальше мы получаем валидное состояние с погодой – Good;

  • переключаем наш сценарий запросом CONNECTION_RESET_BY_PEER на состояние Conn_reset («Оборвать соединение»);

  • и снова переключаем на хорошее – Good.

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

 

Резюме

 

Как итог всего этого – вы получаете:

  • стабильную проверку позитивных и негативных сценариев, не угрожая продуктовому серверу;

  • вполне параллельно тестируете локально – тестировщики тестируют у себя, одновременно гоняются тесты на сервере, все замечательно;

  • также можете проверять неадекватные ситуации – сбои, менять ответы, если что-то пошло не так, мусор в ответы наваливать.

Все это позволит вам повышать качество ваших продуктов.

 

Полезные ссылки

 

Накину чуть-чуть полезных ссылок, что можно почитать подробнее:

Проекты на GitHub

  • Виджет «Погодка», который я использовал https://github.com/petypen/Pogogka20

  • Мой демо-стенд: https://github.com/KrapivinAndrey/infostart2020-DevOps1c-Mockdemo – можете зайти и посмотреть все сценарии, которые я вам показал. Плюс еще парочка реализованных. Возьмите и попробуйте их локально позапускать, посмотреть, как это все устроено.

 

Вопросы

 

Где взять шаги для фич, чтобы работать с WireMock?

Шаги можно взять там же, у меня в репозитории

Пробовали ли вы использовать OneScript.Web в качестве мок-сервера?

Как я уже сказал, когда пишешь сам, проблема в том, что нужно писать. Первый сценарий мы реализовали на Python, потом переписали на OneScript.Web. Но когда начинается усложнение системы, ты понимаешь, что у тебя есть твой код, теперь тебе еще нужно поддерживать свой мок-сервер. Зачем, если уже люди постарались и написали готовое решение.

Как изменяется состояние сервера? Это какая-то опция в командной строке его запуска?

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

Непонятно, в каком формате смотреть результаты тестов.

Результаты тестов смотреть в привычном формате – Allure, Junit. Как обычно, мы проверяем результаты нашего тестирования в фреймворке тестирования – например, Vanessa ADD. Мы не тестируем API, мы тестируем поведение нашей системы – мы отправляем запрос, ожидаем, что поле будет иметь такое значение. Если это не так, очевидно, что тест провален.

 

*************

Данная статья написана по итогам доклада (видео), прочитанного на онлайн-митапе "DevOps в 1С: Тестирование и контроль качества решений на 1С".

См. также

DevOps и автоматизация разработки Тестирование QA Программист Пользователь Платформа 1С v8.3 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Платные (руб)

Автотесты 1С - готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарий – feature-файл, разработанный с помощью vanessa-automation. Запуск сценария выполняется интерактивно с помощью vanessa-automation или с помощью vanessa-runner в CI-системах. Доступно тестирование тонкого клиента. Поддерживаемые версии конфигураций 1С:Зарплата и Управление Персоналом 3 и версии КОРП: 3.1.30.57.

2160 руб.

05.08.2024    1278    12    1    

7

Тестирование QA DevOps и автоматизация разработки Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет Налоговый учет Платные (руб)

Готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарии возможно использовать как для vanessa-automation, так и для СППР. Поддерживаемые версии конфигураций ERP2 и КА2: 2.5.17.113.

2400 руб.

04.07.2022    8368    38    1    

29

Тестирование QA DevOps и автоматизация разработки Программист Пользователь Платформа 1С v8.3 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Налоговый учет Платные (руб)

Автотесты 1С - готовые тестовые сценарии, предназначенные для регресс-тестирования функционала конфигурации после обновления типовым релизом. Сценарии проверяют интерактивное заполнение форм документов, справочников и результат проведения документов. Сценарий – feature-файл, разработанный с помощью vanessa-automation. Запуск сценария выполняется интерактивно с помощью vanessa-automation или с помощью vanessa-runner в CI-системах. Доступно тестирование тонкого клиента. Поддерживаемые версии конфигураций 1С:Бухгалтерия предприятие 3.0 и версии КОРП: 3.0.156.30.

1800 руб.

20.01.2022    7783    19    0    

13

Облачные сервисы, хостинг Linux Тестирование QA Сервера Системный администратор Программист Платформа 1С v8.3 Бесплатно (free)

Завершающая публикация цикла "В облако на работу:.. Рецепты от Капитана", в ходе которых был собран полнофункциональный рабочий контур 1С в сети на отечественной Ред ОС. С веб-серверами, доменной авторизацией, архивированием, отказоустойчивостью и прочая, прочая... В этой статье мы определяемся с быстродействием системы, проводим нагрузочное тестирование и отпускаем ее в свободное плавание (зачеркнуто) выпускаем ее в продуктовый контур, где, конечно же, придется отлавливать ошибки, мониторить состояние и т.п.

31.10.2024    1308    capitan    0    

0

Журнал регистрации Тестирование QA Программист Бесплатно (free)

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

21.10.2024    2782    leemuar    8    

22

Тестирование QA Системный администратор Программист Платформа 1С v8.3 Бесплатно (free)

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

30.08.2024    1292    Scorpion4eg    6    

7

Тестирование QA Программист Платформа 1С v8.3 Бесплатно (free)

Иногда возникают ситуации, когда надо развернуть тестовую базу клиента / свою на серверах Windows или Linux. Тестовые базы могут понадобиться в разных ситуациях: у клиента ошибка, на нашей базе она не воспроизводится, реализуем новый функционал и хотелось бы протестировать на Linux и т.д. А теперь представим, что это все на потоке. Что тестовых баз 1С не одна, а 20-30. И получаем проблему, что непонятно, занята она сейчас кем-то или нет. Предлагаю вариант решения этой проблемы.

28.06.2024    1511    Diversus    12    

5
Оставьте свое сообщение