Как запускать тесты API с помощью Newman и отправлять результаты в Telegram
8 ноября 2022 г.Всем привет!
Как насчет того, чтобы запускать свои коллекции запросов API Postman и автоматически получать содержательный отчет прямо в Telegram? В этой статье я покажу вам, как реализовать этот трюк в одном небольшом скрипте! 🔥
Прежде всего, уместно отметить, что данная статья является лишь обучающим примером создания небольшой части конвейера непрерывной интеграции, которую можно легко выполнить локально с помощью Node.js. Это поможет вам попрактиковаться в запуске коллекций с (или без) выполнением тестов и отправкой запросов API с использованием узловых модулей и без Postman. Но для практического использования есть много отличных встроенных решений для наиболее широко известных инструментов CI, которые вы легко можете найти в свободном доступе. ♾️
Экспорт исходной коллекции и окружения из Postman 🚀
Чтобы запускать какие-либо наборы запросов API, нам сначала нужно сделать их доступными в виде отдельного файла, который можно получить, например, из Postman. Для этого случая в моем Почтальоне у меня была коллекция для проекта CRM "ClientBase v5" который содержит несколько десятков наиболее вероятных API-запросов и более 400 встроенных тестов, а в некоторых случаях и скрипты предварительного запроса.
Во всех тестах я намеренно использовал синтаксис BDD Chai Assertion Library, чтобы упростить разработку. автоматизированные тесты на их основе. Некоторые тесты содержат одни и те же утверждения, но используют немного другой синтаксис. Дело в том, что синтаксис библиотеки Postman и Chai позволяет нам реализовать конкретное утверждение по-разному, что, безусловно, здорово. 🍵
Все, что мне нужно было сделать, это экспортировать коллекцию в виде файла json и сохранить его локально. Далее мне будет важно знать ==только путь к этому файлу==.
Я также экспортировал в виде json набор переменных среды. Большинство этих переменных были созданы как динамические, другими словами, они генерируются с использованием библиотека фейкеров. Значения переменных, как видно на картинке, изначально не заданы и заполняются автоматически в процессе выполнения запросов:
Если вам интересно, эта коллекция Postman доступна ==здесь == (все еще растет).
API Telegram Bot 🤖
Как я уже упоминал, после запуска сбора и создания отчета я отправлю уведомление и этот отчет в Telegram. Причем здесь важно отметить, что получателем в данном случае может ==не обязательно быть Telegram==. Например, ==это может быть Slack или любой другой ресурс==, доступный для взаимодействия через API.
Что ж, для обучающего примера я выбрал Telegram, потому что просто хотел больше узнать о возможностях Telegram Bot API а>сильный>. Для начала мне нужно было выбрать существующую или создать новую группу Telegram, чтобы получать туда уведомления и отчеты. Это может быть любая группа Telegram (общедоступная или закрытая). Поэтому я создал новую группу под названием "Оповещения API". Самым важным шагом было ==получение идентификатора чата== моей группы. И мне это удалось очень легко с помощью специального бота внутри Telegram — бота «Получить мой ID». Я только что переслал этому боту одно сообщение из моей только что созданной группы, и у меня уже был идентификатор чата. Были и другие способы сделать это, но этот показался быстрее.
Тогда оставалось только создать бота, с которым я собирался взаимодействовать с помощью API запросов. Ну, я сделал это еще быстрее, и ==здесь== подробное руководство по созданию Telegram бот с помощью @Botfather. Здесь главное ==получить от Botfather уникальный токен== аутентификации бота, который выглядит примерно так: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
. Далее я добавил своего нового бота в созданную группу "API alerts" и дал админу разрешение на отправку сообщений в группу.
Кажется, нет смысла более подробно объяснять этот шаг, потому что здесь все предельно просто и в Интернете есть масса инструкций, как это сделать.
Что ж, пришло время создать проект.
Создание проекта и установка необходимых зависимостей 🗂️
Выполнив подготовительные действия в Postman и Telegram, я, наконец, создал новый проект в IDE, инициализировал его и приступил к установке необходимых зависимостей. Поэтому для запуска коллекции я использовал Newman, средство запуска коллекции для Postman из командной строки. Для того, чтобы установить Newman локально в проект в виде библиотеки, использовалась следующая команда:
npm i newman
Что касается отчета о работе коллекции, в целом, мы можем интегрировать его с нашим конвейером CI с помощью интерфейса командной строки Postman или Newman в качестве чистого средства запуска коллекции из командной строки и генерировать некоторые отчеты, например, с помощью Allure или хотя бы JUnit. Однако мы также можем использовать генераторы отчетов Newman и получать как минимум (а иногда и гораздо больше) информативные и удобные для пользователя отчеты с целевой страницей сводки в стиле панели и набором различных вкладок, содержащих подробную информацию о запросе.
Чтобы быть более точным, я часто предпочитаю использовать html-extra reporter Дэнни Дейнтона, который — это обновленная версия стандартного Newman HTML Reporter, содержащая более подробный вывод данных и несколько полезных дополнений. 📑
Итак, этот репортер был установлен в проекте с помощью команды:
npm i newman-reporter-htmlextra
Помимо использования в проекте переменных среды, мне также понадобился еще один модуль dotenv, загружающий переменные среды из файл .env в process.env. После установки этого модуля командой:
npm i dotenv
Я создал файл .env в корне проекта, в который поместил необходимые переменные среды:
- COLLECTION_PATH – путь к локально размещенному json-файлу с моей коллекцией Postman;
- ENVIRONMENT_PATH — путь к локально размещенному файлу json с переменными среды, который также был экспортирован из Postman;
- TOKEN — токен моего Telegram-бота;
- CHAT_ID – идентификатор чата моей группы Telegram.
В моем случае это выглядело так (значения чувствительных переменных конечно изменены):
COLLECTION_PATH=C:/Users/user1/.vscode/Newman-Collection-Run-Reporter-on-CRM-Project-example/CRM_Project_ClientBase_v5_collection.json
ENVIRONMENT_PATH=C:/Users/user1/.vscode/Newman-Collection-Run-Reporter-on-CRM-Project-example/ClientBase_v5_environment.json
TOKEN=270485614:AAHfiqksKZ8WmR2zSjiQ7_v4TMAKdiHm9T0
CHAT_ID=-1002956968
Ну вот, основные зависимости установлены, пора кодить. 👨💻 Для этого я создал в корне проекта файл runner.js, в который включил первый блок кода:
require('dotenv').config()
const newman = require('newman');
//Running collection with Newman, report generation:
newman.run({
collection: process.env.COLLECTION_PATH.toString(),
environment: process.env.ENVIRONMENT_PATH.toString(),
reporters: ['htmlextra'],
iterationCount: 1,
reporter: {
htmlextra: {
export: 'report' + '/report.html',
// template: './template.hbs'
// logs: true,
// showOnlyFails: true,
// noSyntaxHighlighting: true,
// testPaging: true,
browserTitle: 'My Newman report',
title: 'My Newman Report',
titleSize: 4,
// omitHeaders: true,
// skipHeaders: "Authorization",
// omitRequestBodies: true,
// omitResponseBodies: true,
// hideRequestBody: ["Login"],
// hideResponseBody: ["Auth Request"],
showEnvironmentData: true,
// skipEnvironmentVars: ["API_KEY"],
// showGlobalData: true,
// skipGlobalVars: ["API_TOKEN"],
// skipSensitiveData: true,
// showMarkdownLinks: true,
showFolderDescription: true,
// timezone: "US/Boston",
// skipFolders: "folder name with space,folderWithoutSpace",
// skipRequests: "request name with space,requestNameWithoutSpace",
displayProgressBar: true
}
}
})
Как видите, в полях коллекция
и environment
я поместил COLLECTION_PATH
и ENVIRONMENT_PATH
в качестве переменных среды, используя свойство process.env.
В настройках репортера в поле export
я ==указал каталог== куда Newman будет сохранять файл моего отчета. Другими словами, после того, как Newman завершит свою работу, в корне проекта появится новый каталог report, в котором находится report.html em> будет размещен.
Кроме того, как пользователи, мы можем ==настраивать шаблоны отчетов== только для своих нужд. Html-extra Reporter позволил нам сделать это, раскомментировав строки кода внутри поля htmlextra
.
Проблема асинхронности и ее решение 💡
На этом этапе мы можем столкнуться с проблемой, связанной с асинхронным выполнением прохода сбора и отправкой вызова API в Telegram. Понятно, что Ньюману потребуется какое-то время, чтобы прогнать все запросы и вложенные тесты, а также сгенерировать отчет. Конечно, это всего пара секунд, но т==выполнение кода ускорит отправку звонка в Телеграм, не дожидаясь Ньюмана==.
Чтобы избежать проблемы асинхронности и обеспечить последовательное выполнение блоков скрипта, пришлось обратиться к помощи модуля DeAsync, который превращает асинхронную функцию в синхронную. Он был установлен с помощью команды:
npm i deasync
Этот пакет позволил мне использовать loopWhile(predicateFunc), где predicateFunc — это функция, возвращающая логическое условие цикла. Поэтому я добавил в свой код следующий блок:
let done
newman.run({
//...
})
.on('start', () => {
console.log(`Running a collection. Please wait a few seconds...`)
}).on('done', () => {
done = true
})
require('deasync').loopWhile(() => {
return !done
})
Что ж, осталось только настроить вызовы API к Telegram.
Отправка файлов с помощью Fetch API 📨
На этом этапе мне нужно было настроить отправку ==двух вызовов API== в Telegram: первый с уведомлением об успешном завершении сбора и второй с отчетом в формате HTML. Эти звонки должны были пойти сразу после того, как Ньюман завершит свою работу. Для реализации этой задачи, безусловно, можно использовать любые HTTP-клиентские библиотеки для Node.js, доступные в виде npm-пакетов (Axios, Got, SuperAgent и т. д.), но я обратился к Fetch API. Для его установки использовалась следующая команда:
npm i node-fetch
В коде я использовал метод fetch(). с обычным синтаксисом промисов:
const fetch = require('node-fetch')
//Sending an information notification to Telegram:
const url1 = `https://api.telegram.org/bot${process.env.TOKEN}/sendMessage?chat_id=${process.env.CHAT_ID}&text=
Your collection has been successfully run. The results are contained in the attached report below.`
fetch(url1, {
method: 'GET'
})
.then((res) => res.json())
.then((res) => {
console.log(res)
})
.catch((error) => {
console.log(error)
})
Как видите, константа url1
содержит строку с URL, на который отправляется запрос. Это ==стандартный шаблон==, который устанавливается Telegram API. В соответствии с этим шаблоном я включил токен и идентификатор чата внутри URL-адреса в качестве переменных среды, которые я вытащил из файла .env с помощью свойства process.env.
Следующий запрос оказался чуть сложнее в реализации, потому что внутри него нужно было отправить файл report.html, который сначала нужно было ==конвертировать== с использованием типа кодировки multipart form-data. Поэтому для создания читаемых потоков «multipart/form-data» мне нужно было использовать Form-Data. библиотека. Для того, чтобы установить его локально, использовалась следующая команда:
npm i form-data
Основываясь на синтаксисе этой библиотеки, я создал форму с одним полем, содержащим файловый поток файла report.html strong> и передал его методу fetch() для отправки в качестве тела запроса. В результате получился следующий блок кода:
const FormData = require('form-data')
const fs = require('fs')
//Sending html-report to Telegram:
const url2 = `https://api.telegram.org/bot${process.env.TOKEN}/sendDocument?chat_id=${process.env.CHAT_ID}`
let readStream = fs.createReadStream('report/report.html')
let form = new FormData()
form.append('document', readStream)
fetch(url2, {
method: 'POST',
body: form,
}
)
.then((res) => res.json())
.then((res) => {
console.log(res, 'The report was successfully sent to
Telegram')
})
.catch((error) => {
console.log(error)
})
Что ж, наконец пришло время выполнить написанный скрипт. Однако в файле package.json я ранее изменил команду для запуска сценария «тест», написав:
"test": "node runner.js"
Когда я запустил скрипт с помощью команды:
npm test
тут же в терминале появилась специальная зеленая полоска, показывающая ход выполнения сбора:
После окончания прогона я получил два сообщения с уведомлением и файлом report.html прямо в моей группе Telegram "API alerts": ✉️
Отлично, давайте откроем полученный отчет и посмотрим, что это такое:
Кроме того, в терминале я получил тело ответа от Telegram API, содержащее подробную информацию о том, что и куда было отправлено:
Вместо заключения 👋
В этой статье я постарался максимально подробно описать весь процесс, от экспорта коллекции Postman до получения отчета о ее работе в Telegram. Я надеюсь, что повторение шагов, которые я сделал, поможет вам зарядить свои навыки API. 💪
Этот проект с подробными инструкциями по установке и использованию полностью доступен ==здесь==.
Оригинал