И снова здравствуйте! Меня зовут Ярослав, и я лидер направления автоматизации тестирования в Центре развития финансовых технологий Россельхозбанка. В этой статье я поделюсь своим опытом создания Telegram Bot-а для автоматизации тестирования.
Как появилась идея создать Telegram Bot для автотестов?
Мы хотели облегчить пользователям громоздкую цепочку действий из 4 шагов:
1) подключение к сети;
2) вход в VDI;
3) вход в Jenkins;
4) запуск автотестов или проверка окончания сборки.
Тогда нам пришла в голову мысль, что Telegram Bot может решить эту задачу.
Забегая вперед, скажу, что это «зашло». Реакция пользователей после запуска бота была позитивной: «Удобно!», «Круто!», «А что, так можно было?».
Определяем функции бота.
Дано:
1) Собственный Jenkins (его поддерживает команда автоматизации);
2) Настроенные проекты, подключенные к автоматизации по одному шаблону и соответственно работающие одинаково;
3) Язык программирования — Java.
В этой статье я подробнее рассказываю о внутренних процессах проекта.
Задача:
1) Запустить автотесты из Telegram;
2) Понять состояния сборки из бота.
Исходя из этих критериев, мы можем выделить команды, которые будут в главном меню бота:
1) Запуск автотестов;
2) Получение очереди сборок;
3) Подписка на уведомления.
Начинаем создавать Telegram Bot.
1. Создаем бота через BotFather:
В свободном доступе находится много инструкций по созданию бота в Telegram, однако стоит обратить внимание на несколько моментов:
1) Начните со ссылки на BotFather;
2) Сохраните «имя бота»;
3) Сохраните Token «token to access the HTTP API».
Последние два параметра нам пригодятся в дальнейшем.
2. Тестируем отправку сообщений
a) Нужно отправить боту сообщение. Для этого в браузере вставляем следующий URL:
https://api.telegram.org/bot5555555555:AAA-CCmmQQwKK1s5dGGttt7AAAAAAAAAA7oo/getUpdates
"5555555555:AAA-CCmmQQwKK1s5dGGttt7AAAAAAAAAA7oo" — это ваш token бота, который я просил вас сохранить (пункт 1.3).
Получаем ответ следующего формата:
{
"update_id": 213155906,
"message": {
"message_id": 3312,
"from": {
"id": 630654728,
"is_bot": false,
"first_name": "NAMENAME",
"username": "myUserName",
"language_code": "ru"
},
"chat": {
"id": 777777777,
"first_name": "NAMENAME",
"username": "myUserName",
"type": "private"
},
"date": 1063328708,
"text": "Privet Andrei"
}
}
В блоке «chat» будет "id":777777777. Копируем его.
b) В браузере вставляем следующий URL:
https://api.telegram.org/bot5555555555:AAA-CCmmQQwKK1s5dGGttt7AAAAAAAAAA7oo/sendMessage?text=Privet Andrei&chat_id=777777777
где «5555555555:AAA-CCmmQQwKK1s5dGGttt7AAAAAAAAAA7oo» — это ваш token бота (пункт 1.3), а «777777777» — это ваш chat «id» (пункта 2.a.)
Получаем ответ следующего формата:
{
"ok": true,
"result": {
"message_id": 3610,
"from": {
"id": 5511726085,
"is_bot": true,
"first_name": "NAME",
"username": "Name_bot"
},
"chat": {
"id": 610044722,
"first_name": "NAMENAME",
"username": "myUseName",
"type": "private"
},
"date": 1065329540,
"text": "Privet Andrei"
}
}
В чате у вас появится сообщение от бота "Privet Andrei".
3. Подготовим Jenkins.
3.1 Создаем и настраиваем пользователя для запуска автотестов
3.1.1 Создаем пользователя
Путь в Jenkins: Настроить Jenkins – База данных пользователей Jenkins.
Или URL – «http://JenkinsHost:JenkinsPort/manage/securityRealm/»
3.1.2 Раздаем права на запуск job в Jenkins созданному пользователю.
В зависимости от ваших настроек безопасности раздаем права на запуск job или добавляем в группу с нужными правами, если такая есть.
3.1.3 Создаем Api Token
Авторизуемся под созданным пользователем и заходим в настройки пользователя.
В настройках ищем пункт «Api Token».
Создаем его и сохраняем. Он пригодится для запуска Job.
Далее будем называть его TOKEN_NAME.
3.1.4 Тестируем запуск Job-ы
Jenkins предлагает следующую схему:
Use the following URL to trigger build remotely:
JENKINS_URL/job/ProjectName /job/FOLDER/job/JobName/build?token=TOKEN_NAME or /buildWithParameters?token=TOKEN_NAME
Эту подсказку можно найти в редакторе Job-ы в пункте «Trigger builds remotely (e.g., from scripts)».
У нас в проектах есть 2 параметра: BRANCH (Ветка) и TAG (Тег для запуска).
Следовательно, URL для запуска будет выглядеть следующим образом:
JENKINS_URL/job/ProjectName/job/FOLDER/job/JobName/buildWithParameters?token=TOKEN_NAME&TAG=@all&BRANCH=test
Вставляем URL в браузер, запускаем и проверяем, что в Jenkins стартовала сборка Job-ы.
4. Разворачиваем базу данных.
Вы можете использовать любую подходящую для вас базу данных, в нашем случае это H2. База данных нам понадобится для хранения состояния пользователя и некоторых его данных, например, «chat_id» Telegram. Найти инструкцию по установке можно на просторах интернета, однако вам пригодиться ссылка для скачивания: «https://h2database.com/html/main.html».
5. Делаем каркас основных подкапотных функций бота.
Для реализации функций бота на java мы использовали
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>lastVersion</version>
</dependency>
Необходимые функции бота:
a. читать сообщения;
b. отправлять сообщения;
c. создавать, изменять, читать данные пользователя в БД;
d. создавать, изменять, читать состояние пользователя в БД (где он находится и какую кнопку выбрал);
6. Реализуем функцию «Запустить автотесты»
Чтобы запустить тесты, нужны следующие данные:
a. название проекта;
b. стенд;
c. ветка;
d. тег;
e. TOKEN_NAME из пункта 3.1.3
Из собранных данных можно составить URL для запуска
JENKINS_URL/job/Название проекта/job/FOLDER/job/Стенд/buildWithParameters?token=TOKEN_NAME&TAG=Тег&BRANCH=Ветка
Схема для понимания, почему URL выглядит таким образом:
С помощью сохранения состояний в БД и кнопок меню в Telegram получаем эти данные и «запускаем» собранный URL.
7. Реализуем функцию «Получить очередь сборок»
Эта функция должна возвращать:
a. список проектов, стоящих в очереди;
b. список проектов, которые сейчас собираются;
Чтобы увидеть оба пункта, нам пригодится api Jenkins-а.
Для получения очереди достаточно обратиться по URL
http://JenkinsHost/queue/api/json
либо
http://JenkinsHost/queue/api/xml
в зависимости от того, с каким форматом вам удобнее работать.
Для получения проектов, которые собираются, используйте URL:
http://JenkinsHost/computer/api/json?tree=computer[executors[currentExecutable[url]],oneOffExecutors[currentExecutable[url,actions]]]
Вернутся сборщики и проекты, которые собираются.
Формат возвращаемого сообщения:
Место в очереди - N
Job Name - ProjectName/job/Folder/job/Stand/"
TAG - @all
BRANCH - test
Build Status - В очереди или Собирается
8. Реализуем функцию «Подписка на уведомления»
Для реализации функции отправки уведомлений есть несколько путей:
1) Сложный. Нужно собрать все «chat_id» переписки пользователей с ботом и по всему списку «chat_id» по триггеру рассылать сообщения по очереди;
2) Легкий. Создать отдельный канал в Telegram для публикации своих уведомлений и сделать Bot-а администратором. Таким образом все, кто подписан на канал, получат уведомления. По сути у вас будет один «chat_id», на который вам нужно будет отправлять уведомления.
Мы выбрали второй вариант. Во-первых, так быстрее. Во-вторых, чат пользователя с ботом не забивается уведомлениями из Jenkins. Автотесты собираются достаточно часто.
Способ отправки сообщения такой же, как и в пункте 2.b, меняется только «chat_id».
Куда и как отправлять уведомления мы определили — теперь нужно реализовать эту функцию. Мы хотим понимать, когда Job-а начала сборку и когда закончила её. Формат уведомления:
Job_Name - ProjectName/job/Folder/job/Stand/"
Build_Number – N
TAG - @all
BRANCH - test
Build_Status – Start/Finish
Allure_URL – JenkinsHost/ProjectName/job/Folder/job/Stand/BuildNumber/allure/
где «Allure_URL» возвращаем только в конце сборки.
Чтобы отправить сообщения, мы использовали 2 плагина для Jenkins:
a. Execute Groovy script — используем для отправки сообщения о старте сборки.
b. Groovy Postbuild — используем для отправки сообщения об окончании сборки.
Результат
1) Автотесты можно запускать из любой точки, где есть Telegram и интернет.
2) Процесс запуска автотестов ускорился с 1 минуты до 10 секунд.
3) Теперь не нужно постоянно заходить в Jenkins, чтобы проверить состояние сборки проекта. Уведомление об окончании сборки придет в Telegram сразу с ссылкой на отчет.
4) Можно посмотреть очередь сборки проектов.
Комментарии (5)
Doman
10.11.2022 17:10+2Не до конца понял - зачем запускать тесты вручную? Если в продукте ничего не изменилось, то тесты запускать незачем. Если в продукте что-то изменилось, то запускать надо до/после изменений автоматически.
Получение упавшего тест-репорта полезно, да.
yaroslav796 Автор
10.11.2022 19:42+1Проект состоит из 11 продуктов, которые собираются отдельно друг от друга. Т.к проект нужно тестировать в целом, то автозапуск при сборке каждого из 11 продуктов будет лишним. + есть ограничения в виде тестовых данных. Здесь они создаются в других системах и часто чистятся. Что тоже накладывает ограничения в виде их подготовки. А так да, есть продукты, которые не зависят от внешних факторов. Там реализован автозапуск из pipeline деплоя на стенд. И там уже только уведомления полезны.
insomnia77
11.11.2022 20:02На мой взгляд, зря потраченное время на разработку велосипеда.
Согласен с предыдущим комментарием, что запускать тесты вручную не нужно. Можно запускать тесты после деплоя изменений на стенд или, например, по расписанию полный регрессионный набор. Если у вас есть зависимости от тестовых данных и 11 продуктов, то добавьте эти зависимости в pipeline и сэкономите кучу времени избавившись от ручных запусков.
В рамках исключения, всегда можно просто зайти в мобильную версию CI/CD и запустить job.
Насчет нотификаций в корпоративный чат - это уже давно реализовано в CI/CD системах и не нужно пилить велосипеды. Например, в Circle CI делается одной строчкой
orbs:
ms-teams-notifier: oktapodia/ms-teams-notifier@1.0.0
Уверен, что Jenkins тоже есть плагины.
alcochtivo
Круть, писал такого же, но на Go, лет пять назад... дальше личного пользования не ушло, и видимо зря) А теперь вот побаловался и сделал тупенького бота, для проверки ответа сервера. Можно добавить урл, который будет дёргаться раз в минуту, и если код ответа не 200, и\или тело ответа равно нулю - бот будет алярмить в личку.
yaroslav796 Автор
Спасибо! Хорошая идея!