Во время разработки часто приходится прибегать к использованию моков – заранее подготовленных ответов сервера. Например, они могут находиться внутри проекта, в специально созданном json-файле. Можно ли вынести их за рамки проекта и дать возможность динамически изменять? Возможное решение этих вопросов я опишу ниже.
Привет, Хабр!
В ходе разработки сервисов, завязанных на API наших партнёров, мы часто сталкивались с проблемами интеграционного тестирования. А именно, с отсутствием возможности у тестировщиков проверить различные сценарии взаимодействия с интегратором. Нам был необходим инструмент, соответствующий следующим требованиям:
удобная интеграция,
простота в понимании и реализации,
быстрая подмена ответов,
удобный интерфейс.
Звучит как идея на хакатон? Так подумали мы и на одном из хакатонов в ATI.SU воплотили её в жизнь.
Откуда идея
Наша команда разрабатывает страничку сервиса «Проверки ATI.SU». Ее бизнес-логика заключается в получении информации о контрагенте, которая позволяет узнать всё о партнере и не нарваться на мошенников.
В нашем случае проверки бывают двух типов:
одношаговые: отправил запрос, получил ответ;
двухшаговые: отправил запрос, сохранил ключ и через определённое время вернулся за готовым отчетом.
В дополнение к этому нас сопровождали проблемы имитации специфичных ответов интегратора или вовсе его неисправности.
Эти задачи мы решали созданием в сервисе статичных моков, однако такой подход не давал тестировщикам возможности их редактировать и создавать новые тест-кейсы. По этой причине к нам пришла идея создания мок-сервиса, способного закрыть наши проблемы, сократить время тестирования и улучшить выпускаемый продукт.
Как с этим взаимодействовать
Пример внедрения мок-сервиса в процесс тестирования представлен на картинке:
В нашем случае есть 2 тестовые машины. Окружение необходимо настроить таким образом, чтобы при выкладке тестируемого сервиса на одну из них, происходила замена базового адреса интегратора. Например:
Выложили на 1 машину:
«IntegratorOptions»: {
«BaseUrl»: «https://driver.ru/«,
},
Выложили на 2 машину:
«IntegratorOptions»: {
«BaseUrl»: «https://mockservice-domain/mockservice/«,
},
По итогу, тестировщик, взаимодействуя со второй машиной, имеет возможность создавать и изменять моки, взаимодействуя с первой, проводить завершающее тестирование.
Как это работает
В качестве базы данных мы взяли MongoDB, в сервисе реализовали ряд CRUD-методов и дополнительную логику:
группирование созданных моков,
переключение моков,
возврат заготовленных ответов.
Группирование созданных моков
При создании тестового шаблона просим задать название группы, куда он будет помещен и в дальнейшем отсортирован. Эта логика необходима для навигации по мокам и удобному поиску.
Теперь его можно найти в поиске в составе группы:
Переключение моков
В нашей логике мок идентифицируется двумя параметрами — адрес и HTTP-метод. При создании похожего шаблона ответа, предыдущий становится неактивным и сервис начинает возвращать новые данные. Эта возможность позволяет их переключать и использовать повторно.
Возврат заготовленных ответов
Основная логика сервиса, также является простой – сервис слушает endpoint, заканчивающийся на «mockservice/», получает из контекста адрес, метод запроса и находит включенный мок, который отдаёт в ответе.
И это всё?
Написанный инструмент кажется примитивным, но способен решать интересные задачи, ограниченные только вашей фантазией.
Приведу пару примеров использования сервиса, появившихся уже после взаимодействия с ним:
Возможность написать цепочки методов: Сервис совершает запрос А, потом запрос B и C. На каждый запрос есть возможность задать моки и по-разному их чередовать.
Возможность на основе мок-сервиса, начать выполнять фронтовую задачу, тестируя ее на заранее продуманном контракте.
Возможность без боли интегрироваться с системами, дающими ограниченный доступ к их API, например, платёжные системы.
Заключение
Мок-сервис не был бы так удобен без своего GUI, что сделало его отличным помощником в тестировании.
Когда мы создавали сервис, нас не покидало ощущение, что мы изобретаем велосипед, что для решения этого вопроса уже есть готовые варианты. Но, учитывая, что проект смог упростить жизнь и открыл для нас новые возможности, мы остались довольны и активно его используем в своих процессах. Спасибо за внимание!
Пример кода можно посмотреть по ссылке.
Может быть, вы писали что-то своё или использовали сторонние решения? Расскажите об этом в комментариях!