Найти тему
Mad Devs

Mad-Fake-Slack — для тестирования ваших ботов, в отрыве от реального сервиса Slack (альфа версия)

mad-fake-slack — это прежде всего, инструмент для тестирования вашего бота, без использования реальных серверов slack. В будущем это будет мощный инструмент для интеграционных и e2e тестов. Как видно, по гифке ниже, при тестировании, что-то может пойти не так :). И чтобы избежать этого, нужно тестировать не на продакшн, а локально, без привязки к реальным сервисам.

-2

В большинстве случаев, интеграционные тесты, за неимением аналогов для реальных сервисов, проводят с использованием “реальных сервисов”.

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

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

Фейковые сервисы (как правильно называть, можно почитать тут), позволяют сократить время тестирования и добавить возможность моделирования конкретной ситуации, без множества предшествующих ей, манипуляций. Если необходимо, чтобы клиент был как бы уже “залогиненным” в слаке, (вы же не будете тестить логин клиента в слак), то фейковый сервис позволяет убрать ненужные действия, ведь вам, нужно тестить бота или приложение, что предоставляет услуги. В этом деле, уже сейчас, может помочь mad-fake-slack. Пока он умеет мало, но уже с этим функционалом можно тестировать простейшие отправки/получения сообщений.

Недостатки фейковых сервисов и любой клиентской библиотеки

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

И тут все зависит конечно, от команды поддерживающей фейковый сервис.

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

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

Из чего состоит mad-fake-slack

  • UI интерфейс очень напоминающий Слак клиент
  • Возможность пред-заполнения данными канал или директ обычного пользователя (через редактирование файлов в папке db) или пользователя приложения, так как все данные хранятся на диске в формате json. Их легко заполнить и изменить.
  • Есть один пользователь, который считается залогиненным (он указывается первым в коллекции пользователей)
  • По умолчанию есть два канала general и random
  • Присутствует пользователь приложения valera (он помечается спец маркой APP), которого также при желании можно изменить.

Дисковое хранилище данных mad-fake-slack

-3

users.json — это файл, в котором хранятся данные об обычных пользователях, ботах и пользователях приложений.

teams.json — тут хранятся данные о командах, в которых может находиться пользователь.

sessions.json — тут хранятся ассоциации md5 хеша токена пользователя и его идентификатора. Для чего это нужно? Так как я не нашел никаких заголовков при соединении бота к ws серверу mad-fake-slack, то стало очевидным, как-то нужно понимать, какой пользователь — бот сейчас привязан к данному сокету. В итоге, родилось такое вот простое решение (приближенно аналогичное реальному решению в слаке). Так как при запросе на метод /api/rtm.connect или /api/rtm.start выдается информация с url для ws сервера (по которому бот и коннектится), можно подсунуть в параметры хеш, идентифицирующий пользователя. Но это, пока что зачатки секьюрити, которую в будущем можно будет также тестировать.

channels.json — тут находятся данные по каналам, которые так же можно легко менять. Этот список возвращается при запросе каналов из /api/channels.list

messages — это папка, в которой хранятся все сообщения. Для упрощения и разделения доступа к сообщениям (выбрана структура “файл на канал”). В качестве идентификатора файла, используется id канала. Таким образом в каждом из CXXXXXXXX.json файлах, хранятся сообщения каналов, в отдельности. Внутри каждого такого файла находится объект, первое свойство которого, хранит мета-информацию и пока там только поле хранящее кол-во записей с неочевидным названием “last_id” (в будущем исправлю этот недостаток). Далее следуют записи типа ключ: объект. Где объект — это запись сообщения с необходимым минимумом полей, а ключ — это значение поля ts — что гарантированно является уникальным ключом с содержанием даты в unix формате + инкрементальное значение.

Есть так же менеджер, импровизированной БД на диске, что позволяет объединить данные из нескольких файлов, по их ключам и выдать клиенту.

Примеры ответов на api запросы

В папке responses находятся примеры положительных ответов на запросы api с названиями методов api, для которых они предназначаются. Сейчас эти файлы используются как болванки ответов, в которых изменяются нужные поля, перед тем как отправить запросившему. Все примеры ответов были взяты с сайта документации апи слака https://api.slack.com/

Про UI

Пользовательский UI основан на Handlebars.js — для рендера на клиенте и express-handlebars — для серверного рендеринга. Это гибридный рендеринг, так как большая часть рендера страниц осуществляется на серверной части. На клиенте, используется реал-тайм прием сообщений через ws соединение. Серверные хелперы и темплейты, переиспользуются на клиенте, очень удобно.

-4

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

Что сейчас доступно через интерфейс?

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

Что предстоит сделать?

  • Индикацию сообщений (красный кружочек для неактивного канала)
  • Парсинг markdown сообщений
  • Отображение более сложных по структуре сообщений
  • Тестирование отправки файлов
  • Кнопки на сообщениях (для реакций)
  • Отображение состояния typing под текстовым полем
  • Возможность добавить канал из UI
  • Возможность добавить нового пользователя
  • Возможность смены статуса текущего пользователя
  • Возможность просмотра RAW сообщения в JSON в канале, чтобы увидеть его структуру “как есть”.
  • Возможность создания треда сообщений
  • Отображение тредов сообщений.
  • Добавление отправки эмодзи
  • Удаление пользователя
  • Удаление приложения
  • Удаление канала
  • Архивирование канала
  • Поддержка слеш-команд

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

Про серверную часть

Она построена на основе express.js и express-ws и позволяет обрабатывать следующие апи вызовы:

  • /api/rtm.connect
  • /api/rtm.start — сейчас пока этот метод выдает ровно столько же информации, сколько и rtm.connect. В будущем ответ будет приведен в соответствие с ожидаемым по документации в api.
  • /api/auth.test
  • /api/channels.list
  • /api/chat.postMessage

Так же присутствует серверный рендер следующих страниц:

/ — главная страница, по умолчанию текущий канал general и соответственно его контент и отображается на странице.

/messages/:id — при клике по названию канала, уходит запрос на сервер, где парсится идентификатор канала и если он есть, в ответ будет возвращена вся страница с отображенным контентом канала. Это касается и директа и открытого канала и пользователя приложения.

/api/chat.postMessage — если отключить JS то форма отправки данных все равно будет работать, так как в этом случае будет отправлен POST запрос на сервер в формате обычной HTTP формы и в ответ будет отображена страница канала, с новым сообщением внутри.

Про тестовое api

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

GET /test/api/db/reset — при отправке запроса на этот URL данные в базе данных в памяти, заново читаются из папки db и таким образом возвращаются в первоначальное состояние. Теперь, необходимо только обновить страницу файкового слака в вашем браузере (если она была открыта до этого).

В будущем кол-во методов помогающих в интеграционном тестировании будет расти по мере необходимости.

По поводу секьюрити

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

Пример реального использования

В папке examples, находится пример rtm бота, что не использует веб хуки, а вместо этого использует ws соединение. Сначала нужно стартовать mad-fake-slack командой npm start. Затем, запустить бота выполнив команду npm run example:rtmbot

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

-5

Так же, можно наблюдать следующую активность в консоле VSCode (так как она используется для локальной разработки + Remote-Containers расширение).

-6

Что необычного в реализациях апи слака, на разных языках

Вот к примеру официальный апи на node.js https://github.com/slackapi/node-slack-sdk, использует внутри стейт-машину и каждый запрос отправляемый на сервер содержит поле id, что увеличивается с шагом в 1. И при этом требуется отсылать в ответе поле reply_to с тем id что был отправлен на сервер.

При этом в библиотеке на python вообще нет привязки к такого рода эхо.

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

If you’re reconnecting after a network problem this initial set of events may include a response to the last message sent on a previous connection (with a reply_to) so a client can confirm that message was received.

Собственно необходимость в reply_to, появляется только в случае, если был разрыв соединения. Но для node.js версии, даже простые ping/pong запросы должны сопровождаться этим полем. Хотя может быть так, что я что-то упустил, но проблем с питон версией не было.

Где можно опробовать в действии mad-fake-slack?

Вот тут https://github.com/maddevsio/mad-fake-slack

Пример интеграционных тестов на jest-puppeeter

В проекте присутствуют примеры интеграционных тестов для бота в папке examples. Которые проверяют его состоятельность и адекватность. Примеры всех тестов можно посмотреть тут. Эти тесты запускаются командой

npm run example:rtmbot:integration
-7

Вот несколько примеров тестов:

Следующий пример, более длинный, для проверки реакции бота, если сообщения отправляются в разные каналы, в данном случае в random и general.

Заключение

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

Ранее статья была опубликована тут.