WSTester – JS библиотека для тестирования веб-сервисов с ВебСокетами
- пятница, 2 февраля 2018 г. в 03:13:25
Добрый день, Хабрасообщество! Как и большинству айтишников, мне нравится создавать что-то новое, классное, нечто способное как-то повлиять на мир или хотя бы принести небольшую пользу другим людям. Надеюсь, что описываемый далее инструмент для тестирования онлайн систем с ВебСокетами как раз такая вещь.

Большинство идей рождаются в результате активной и разнообразной работы, и данная идея не исключение. Для тестирования своей кросс-платформенной игры мне пришлось писать много тестов. Для iOS в среде Xcode предоставляется удобнейший встроенный функционал, (алгоритмы в Java под Android я просто переписывал с Obj-C, решил обойтись без юнит-тестов). На серваке многие алгоритмы можно тестировать изнутри при его локальном запуске, а для проверки правильной обработки HTTP запросов можно легко написать скрипт на Python с библиотекой requests.
Однако когда для взаимодействия клиентов-сервера пришлось добавить канал связи по WebSocket’ам, я не уделил его тестированию нужного внимания. В итоге, в игре не было возможности создать нового юзера через ВебСокеты, а приложение использовало именно их… Глядя на статистику я быстро заподозрил что-то неладное, но принял решительные действия лишь спустя месяц-другой.
Главной причиной появления этой ошибке в production’e было то, что для тестирования ВебСокетов не было видно простых путей – ведь в отличии от HTTP, где у каждого запроса есть ответ, в ВебСокетах можно отправить сколько угодно сообщений на сервер и не получить ответа вовсе; или же ничего не отправлять, зато получить любое количество различных сообщений.
Поискав в Интернете, я не нашёл каких-то рекомендаций по этой теме. Возможно я плохо искал, или возможно эта технология ещё слишком молодая, и для крупных проектов пишутся собственные системы для тестирования, а в малых всё делается вручную. Однако я увидел небольшую пустоту в мировом программном континууме и поспешил её закрыть.
В результате получились JavaScript библиотека WebSocket Testing Engine (вкратце WSTester) и веб-страница для работы с ней через готовый GUI, который принимает JS файл с кодом тестов. Все исходники доступны на ГитХабе.
WSTester работает как конечный автомат – на вход подаются потоки выполнения, они исполняются независимо и последовательно, их можно считать за юнит-тесты. Каждый поток выполнения – это массив или словарь JavaScript, он состоит из юнитов, и в каждый момент времени существует лишь один текущий юнит.
Первым в потоке вызывается юнит с индексом 1, последующие могут быть любыми. Если поток это массив, то следующим считается юнит с индексом равным текущему + 1, но можно и поменять индекс следующего юнита. Если поток является словарём, то в нём всегда нужно самостоятельно указывать индекс следующего юнита.
Структура объекта юнита такова:
{
name: string,
enter: function () {},
task: function (ws, ref) {},
condition: function (data) {},
key: string,
val: any type,
finalise: function (ws) {},
}Поле name используется для вывода информации по юниту, enter и task применяются при переходе к новому текущему юниту, а condition, key, val и finalise при получении нового сообщения.
Успешно выполненным юнит считается тогда, когда полученное сообщение удовлетворит одному из условий:
condition, то юнит завершается успешно, если функция с аргументом полученным сообщением вернёт true или индекс следующего юнита.key и val, то юнит завершается успешно, если полученное сообщение имеет поле с названием равным key и значением этого поля равным значению val. Кстати, если val является массивом, то все его значения будут проверены по отдельности.key, но не val, то юнит завершается успешно, если полученное сообщение имеет поле с названием равным key.Если же с момента запуска юнита не было получено подходящих сообщений в течение заданного времени, то текущие юнит и поток считаются проваленными.
Описанной выше информации достаточно для написания тестов, которые можно запускать через готовый интерфейс WSTester. Значительно больше и подробней о принципах работы можно узнать тут и ещё здесь.
В интерфейсе можно менять разные настройки: адрес WebSockets сервера, время ожидания подходящего сообщения до провала юнита, нужно ли создавать новые подключения для каждого потока, время между юнитами. Эти же параметры можно задать в JS файле тестов для максимальной автоматизации. Также, GUI может принимать файлы тестов по указанному URL или напрямую с компьютера.
При использовании самой JS библиотеки помимо перечисленных опций можно задать функцию вывода лога, функцию, вызывающуюся после переподключения соединения, и функцию, вызывающуюся после исполнения всех тестов с количествами успешных и проваленных потоков.
Основной функционал разрабатывался в рамках проекта вышеупомянутой игры, как аналог тестам по HTTP запросам, однако впоследствии был проверен и расширен в работе с несколькими другими сервисами. Ниже указано несколько тестов, описание и ссылки на файлы и сервисы.
condition; поток как словарь; пропуск юнитов с использованием condition и ref.next.val как массив; args.split.finalise.ref.next; args.split.Стоит отметить, что хотя данные тесты и содержат весь функционал WS Testing Engine, они всё же не достигают каких-либо пределов, оставляя огромный простор для фантазии: можно определить и использовать внешние переменные, функции, объекты и работать с ними в юнитах, можно сделать циклические переходы между юнитами по навороченным правилам, и т.д. Язык JavaScript к таким вещам очень располагает.