Тестирование API с помощью Postman

17.11.21

Интеграция - WEB-интеграция

В статье опишу создании коллекции Postman с тестами для её пакетного запуска.

Скачать исходный код

Наименование Файл Версия Размер
Bitrix API.postman_collection
.json 10,63Kb
1
.json 10,63Kb 1 Скачать

Вводные

  • Написан API для Битрикс (заготовка описана в статье //infostart.ru/1c/articles/1185983/)
  • Добавлен блок обновления остатков PUT /product_remains_by_stock с массивом остатков
  • Программистам Битрикс поставлена задача изменять активность торгового предложения при обновлении остатков исходя из наличия на складе.
  • Нужно проверить доработку

Проблема

Тестирование заключается в 

  • Нажали кнопку выгрузить в 1С
  • Проверили на витрине
  • Если на витрине не нашли, то проверили в админ панели

Тестирование только ручное.

Схема компонентов

 

 

Вариант решения

  • Доработать API для получения информации о элементе торгового предложения
  • Создать коллекцию в Postman описав в ней тесты

Материалы требуемые для работы

  • Варианты проверок, перевод //infostart.ru/1c/articles/1545930/
  • Организация последовательности тестирования (без папок) ссылка
  • Работа с переменными ссылка, на данный момент для меня оптимально использовать "collectionVariables"

Тестовый сайт прикрыт basic аутентификацией, поэтому в блоке подготовки (pre-request Script) на уровне коллекции описываем формирование заголовка.

var CryptoJS = require('crypto-js');

if (pm.collectionVariables.get("basic_username")) {
    var rawStr = CryptoJS.enc.Utf8.parse(pm.collectionVariables.get("basic_username") + ":" + pm.collectionVariables.get("basic_password"));
    var base64 = CryptoJS.enc.Base64.stringify(rawStr);

    pm.request.headers.add({ 
        disabled: false,
        description:{
            content: "Basic Auth",
            type: "text/plain"
        },
        key: 'Authorization', 
        name: 'Authorization', 
        value: 'Basic ' + base64
    });
};

 

Порядок тестирования

1. Проверить доступность API

через GET /ping, проверяем на код ответа 200, если отличается, то прерываем тест

pm.test("Код ответа 200", function () {
    pm.response.to.have.status(200);
});

if (pm.response.code != 200) {
    postman.setNextRequest(null);
}

 

2. Получить список складов

GET /references/stocks, сохранить в переменные, будут нужны для дальнейшей состыковки

const responseJson = pm.response.json();

pm.test("Код ответа 200", function () {
    pm.response.to.have.status(200);
});

pm.test("Массив складов не пустой", function () {
    
    pm.expect(responseJson).to.be.an('array').not.to.be.empty;
});

pm.test("Первый элемент содержит id, xml_id", function () {
    pm.expect(responseJson[0]).have.property('id');
    pm.expect(responseJson[0]).have.property('xml_id');
});

pm.collectionVariables.set("stock_id", responseJson[0]['id']);
pm.collectionVariables.set("stock_xml_id", responseJson[0]['xml_id']);

pm.collectionVariables.set("stocks", JSON.stringify(responseJson));

 

3. Получить элемент торгового предложения

GET /references/offers/?limit=1, преобразовать в uri для запроса, получить отдельно id товара.

const responseJson = pm.response.json();

pm.test("Код ответа 200", function () {
    pm.response.to.have.status(200);
});

pm.test("Массив торговых предложений из одного эдемента", function () {
    pm.expect(responseJson).to.be.an('array').to.have.lengthOf(1);
});

pm.test("Первый элемент содержит id, xml_id", function () {
    pm.expect(responseJson[0]).have.property('id');
    pm.expect(responseJson[0]).have.property('xml_id');
});

arrXMLId = responseJson[0]['xml_id'].split("#");

pm.test("xml_id из двух подстрок", function () {
    pm.expect(arrXMLId).to.have.lengthOf(2);
});

pm.collectionVariables.set("product_xml_id", arrXMLId[0]);
pm.collectionVariables.set("offer_xml_id", arrXMLId[1]);

pm.collectionVariables.set("offer_xml_uri", responseJson[0]['xml_id'].replace("#","_"));

pm.collectionVariables.set("testing_stage", 1);

 

Порядок проверки остатков

  1. проверяю что есть массив остатков
  2. очищаю, проверяю на пустой массив и отсутствие активности
  3. устанавливаю остаток по складу, проверяю остаток и активность

 

4. Проверка

сделана через GET /references/offers/{{offer_xml_uri}}/ в ней же устанавливаю параметры для изменения остатков

const responseJson = pm.response.json();
stocks = JSON.parse(pm.collectionVariables.get("stocks"));
testing_stage = parseInt(pm.collectionVariables.get("testing_stage"));
remains = 100;

pm.test("Код ответа 200", function () {
    pm.response.to.have.status(200);
});

if (testing_stage ==  1) {
pm.test("Часть" + testing_stage +", Есть массив остатков", function () {
    pm.expect(responseJson).to.have.property('store').to.be.an('array');
});
}

if (testing_stage ==  2) {
    pm.test("Часть" + testing_stage +", Массив остатков пустой", function () {
        pm.expect(responseJson['store']).to.be.empty;
    });
    pm.test("Часть" + testing_stage +", Торговое предложение не активно", function () {
        pm.expect(responseJson).to.have.property('active').to.equal(false);
    });
}

if (testing_stage ==  3) {

    pm.test("Часть" + testing_stage +", Остаток совпадает", function () {
        store_obj = {store: parseInt(pm.collectionVariables.get("stock_id")), amount: remains};
        pm.expect(responseJson['store']).to.deep.include(store_obj);
    });

    pm.test("Часть" + testing_stage +", Торговое предложение активно", function () {
        pm.expect(responseJson).to.have.property('active').to.equal(true);
    });

}

if (testing_stage == 1 || testing_stage == 3) {
    remains_by_stock = responseJson['store'].map((item)=> {
        return {
        product: pm.collectionVariables.get("product_xml_id"),
        offer: pm.collectionVariables.get("offer_xml_id"),
        stock: getStockXMLIdById(item['store']),
        remains: 0
        }
    });    
} else if (testing_stage == 2) {
   
        remains_by_stock = [{
        product: pm.collectionVariables.get("product_xml_id"),
        offer: pm.collectionVariables.get("offer_xml_id"),
        stock: pm.collectionVariables.get("stock_xml_id"),
        remains: remains
        }] 
}

pm.collectionVariables.set("remains_by_stock", JSON.stringify(remains_by_stock));
pm.collectionVariables.set("testing_stage", testing_stage + 1);

function getStockXMLIdById(stock_id) {
    stock = stocks.find( item => {
        return item['id'] == stock_id});
    return stock['xml_id'];   
}

 

5. Обновляю остаток

через PUT /references/product_remains_by_stock/by_xml_id/, проверяю на код ответа, возвращаю на проверку

pm.test("Код состояния 204", function () {
    pm.response.to.have.status(204);
});

testing_stage = parseInt(pm.collectionVariables.get("testing_stage"));

if (testing_stage == 2 || testing_stage == 3) {
    postman.setNextRequest("Проверить остатки");
}

 

Запуск коллекции

 

 

 

Получаю одну ошибку, потому что функционал смены активности не реализован.

 

 

Итог

Для написания тестов под Postman нужно базово освоить JavaScript, разобраться с переменными и выражениями для проверки.

В результате получаем удобный инструмент который можно передать заказчику и уменьшить количество вопросов связанных  с обменом.

 

Благодарю за внимание.

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    16179    14    18    

14

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (платформа начиная с 8.3.23). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    18295    10    15    

16

Модуль для обмена "1С:Предприятие 8. УАТ. ПРОФ" с FortMonitor

WEB-интеграция 8.3.8 Конфигурации 1cv8 Автомобили, автосервисы Беларусь Украина Россия Казахстан Управленческий учет Платные (руб)

Расширение предназначено для конфигурации "1С:Предприятие 8. Управление Автотранспортом. ПРОФ". Функционал модуля: 1. Заполнение регистров сведений по подсистеме "Мониторинг", а именно: события по мониторингу, координаты по мониторингу, пробег и расход по мониторингу, текущее местоположение ТС по мониторингу 2. Заполнение путевого листа: пробег по мониторингу, время выезда/заезда, табличная часть ГСМ, места стоянок по геозонам. 3. Отчеты по данным загруженным в регистры сведений. 4. Предусмотрена автоматическая загрузка данных в фоновом режиме (условия работы данной загрузке читайте в описании товара) Модуль работает без включенной константы по настройкам мониторинга. Модуль формы предоставляется с открытым кодом, общий модуль защищен. Любой заинтересованный пользователь, имеет возможность скачать демо-версию расширения.

22656 руб.

25.05.2021    13039    34    8    

13

Автоматическая загрузка файлов (например, прайс-листов) из электронной почты, FTP, HTTP, их обработка и выгрузка на FTP (на сайт) и для других целей

Прайсы WEB-интеграция Ценообразование, анализ цен Файловый обмен (TXT, XML, DBF), FTP Автомобили, автосервисы Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Программа с заданным интервалом времени (или по ручной команде) скачивает файлы (например, прайс-листы поставщиков) из различных источников: письма электронной почты, FTP или HTTP-адреса, и сохраняет их в каталог упорядоченной структуры. При этом извлекает файлы из архивов, может переименовывать файлы и менять их формат (csv, xls, txt). Можно настроить выгрузку обработанных файлов на сайт (через FTP-подключение). Программа будет полезна компаниям, у которых есть большое количество поставщиков и/или прайс-листы поставщиков обновляются часто (необязательно прайс-листы, файлы могут быть любого назначения). Собранные таким образом актуальные версии прайс-листов можно выгрузить с помощью программы себе на сайт (или на любой FTP-сервер) или выполнить другие необходимые задачи.

25200 руб.

28.05.2015    85576    26    51    

50

Интеграция с сервисом vetmanager

WEB-интеграция Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разрабатывалась для загрузки документов из Ветменеджер в 1С: Бухгалтерия 3.0

12000 руб.

02.02.2021    16683    43    49    

24
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. malikov_pro 1299 17.11.21 09:07 Сейчас в теме
(1) У Вас базовые вещи и скриншоты, у меня скриптинг, посмотрите предыдущие статьи по этой теме.
Статей "как нажать кнопку" полно, а статей как собрать решение которое можно передать клиенту мало.

На текущий момент у меня вопрос по кодогенерации для 1С https://github.com/postmanlabs/postman-code-generators/issues/546, но уровня владения JS не хватает.
Вы знали что кодогенератор Postman для Java тестируется не только синтаксически и юнит, но и сборкой с прогоном в целевой системе и параллельным прогоном через Newman? Как запустить в контексте 1С? На сколько различаются реализации HTTP клиента в 1С и OneScript?

Описание настройки Newman в связке с системой логирования или allure на русском языке видели?
3. 8095_tores 58 17.11.21 09:51 Сейчас в теме
(2)
по кодогенерации для 1С посмотрите на приложение anti_swagger (https://github.com/oscript-library/anti_swagger)
4. malikov_pro 1299 17.11.21 17:57 Сейчас в теме
(3) Благодарю за ссылку,
1. в описании ссылка на cli некорректная
2. но реализация на OneScript, от 1С реализация HTTP клиента немного отличается.
3. делать блоки кода по спеке - отдельная специфика близкая к "Automated SDK Generation".
От postman запроса: проверил запрос, сгенерировал заготовку нужно функции, с помощью генератора для python за час сделал скрипт интеграции гугл календаря и zoom.

"//TODO Реализовать поддержку коллекций Postman для создания кода 1С" - коллекция <> спека на API.

По хорошему нужно посмотреть вариант реализации, прогнать по RealWorld например, но там openapi: 3.0.1
5. malikov_pro 1299 18.11.21 06:09 Сейчас в теме
(3) посмотрел выступление с Event,
в коде нет listener-ов (той же аутентификации) и wrapper (для выдачи в нескольких форматах),
c OAP 3 уже есть реализация https://infostart.ru/public/1257654/
интересно посмотреть как формируете спеку для нормального формирования mock-сервера, немного напрягает что postman прогоняет его через свои сервисы, вариант использовать https://www.mock-server.com/mock_server/using_openapi.html
6. 8095_tores 58 18.11.21 10:07 Сейчас в теме
(5) попробую отвечать по порядку.
Видимо вышло недопонимание, к сожалению.

То, что я скидывал - делает серверную часть на 1С по спецификации OpenAPI 3.0.0

Реализовано в виде приложения oscript куда на вход отдается спецификация, а на выходе получается уже расширение для 1С.

Судя по тому, что пишите Вы - вам нужен генератор кода 1С по коллекциям Postman. Кода для клиента. Только зацепившись за фразу "кодогенерации для 1С" я и скидывал приложение которое можно использовать для Ваших целей.

И я не говорил, что оно прям полностью Вам подходит или что в нем нет проблем или недочетов.

(5)
в коде нет listener-ов (той же аутентификации)


Вы правы, аутентификация, как и авторизация, пока не внесены в шаблоны по формированию. Так как мы внутри еще не пришли к единому мнению по поводу этого функционала. Будет круто, чтобы были какие-то предложения со стороны.

(5)
wrapper (для выдачи в нескольких форматах)


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

(5)
c OAP 3 уже есть реализация https://infostart.ru/public/1257654/


Это видели, когда начинали работу над библиотекой. Архитектура и подход (сервисы "сделай все" и обвязка на уровне справочников/регистров внутри базы) не понравились. API должно оставаться API и не выходить на уровень базы. Решили начать с спецификации OpenAPI, а не с коллекций Postman. Особенно с учетом того, что есть приложения, которые уже конвертируют Postman Collection в OpenAPI Specification 3 - https://github.com/kevinswiber/postman2openapi

Нарастить до функциональность - тоже не проблема. Были бы желающие на это.

(5)
интересно посмотреть как формируете спеку для нормального формирования mock-сервера


ну "нормального" mock-сервера у нас пока нет. Используем то, что дает Postman так как пока плотно на нем сидим. Так что пока нечем похвастаться в этом направлении.

Был рад помочь (если помог).
7. malikov_pro 1299 19.11.21 10:19 Сейчас в теме
(6) "Видимо вышло недопонимание, к сожалению." - нормальный рабочий процесс состыковки моделей.
Я за обсуждения задачи/проблемы работы с HTTP в рамках 1С группой заинтересованных лиц.
"И я не говорил, что оно прям полностью Вам подходит или что в нем нет проблем или недочетов." - не принимайте на свой счет, инструментов по HTTP и так немного, позитивнее.


"Это видели, когда начинали работу над библиотекой. " - https://infostart.ru/1c/articles/1131305/, мой подход к решению вопроса, шел от одной точки входа на сервис и роутингом через код, из за отсутствия regexp сделано несколько неудобно. Вариант реализации перенял от symfony (PHP). В вашей реализации когда на каждую "ручку" генерится структура имеет ограничение, пример
  $regexRequirements = [
        'id' => '\d+',
        'xml_id' => '[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}',
]

 $routes->add($controllerName . 'getById', (new Route("/{id}/"))
        ->addDefaults([
            '_controller' => [$class, 'getById']
        ])
        ->setMethods(['GET'])
        ->setRequirements($regexRequirements)
    );

$routes->add($controllerName . 'getByXMLId', (new Route("/{xml_id}/"))
            ->addDefaults([
                '_controller' => [$class, 'getByXMLId']
            ])
            ->setMethods(['GET'])
            ->setRequirements($regexRequirements)
        );


Показать


"Трансформация ответа в разные форматы" - это к теме одной точки входа чтобы в каждой функции не писать обращение к листенеру.
"начать с спецификации OpenAPI, а не с коллекций Postman" - и верно сделали т.к. коллекция это спецификация тестирования

"ну "нормального" mock-сервера у нас пока нет" - нужен кейс использования (сам пока не придумал) и спека под него. Могу поднять на https://www.mock-server.com/mock_server/using_openapi.html, порядок настройки опишу в статье.

"Особенно с учетом того, что есть приложения," - они в JS экосистеме и используют общую модель https://github.com/raml-org/webapi-parser
8. malikov_pro 1299 19.11.21 10:51 Сейчас в теме
(6) На выступлении увидел что используете MULE ESB как middleware. Какой оверхед дает, на сколько сложно ставить/администрировать, какие задачи им решаете? Как вариант ставить "API gate" перед 1С, а с HTTP сервисом работать в формате RPC.

"на выходе получается уже расширение для 1С." - Как мержите с кодом в 1С если он уже с наполнением кодом функций?
9. 8095_tores 58 19.11.21 11:03 Сейчас в теме
(8)
В свое время делал доклад на митапе по этому поводу. Потом его выложили в виде статьи.

https://infostart.ru/1c/articles/1486937/

Администрировать не сложно. Разрабатывать тоже удобно. Напоминает работу в конфигураторе для 1С-ника. Кубики набросал, переменные окружения указал, а платформа 1С AnypointStudio за тебя исходники сделала. Взял исходники и запушил.

Захотел - добавил асинхронность. Захотел - добавил кеширование. Захотел - логирование. Но понятно, что все руками, а не "оно само как то"

MULE ESB - рекомендую. Только не последнюю 4.2, а 3.9. Оно конечно немного устарело, но FreeWare коннекторов на 3.9 все таки больше.

Минус - "условная бесплатность" и отсутствие инфы по коннектору, нужна ли для него лицензия.

Но плюсы явно перевешивают минусы.

(8)
Как мержите с кодом в 1С если он уже с наполнением кодом функций?


пока используем в основном для новых функций ну и явных изменений в существующих. Мержится пока руками разработчика 1С. Она из идей в будущем - автоматический мерж в gitlabCI. При правильном проектировании самого расширения это не должно стать проблемой. Но пока и без этого есть с чем поработать.
10. malikov_pro 1299 19.11.21 14:01 Сейчас в теме
"Но понятно, что все руками, а не "оно само как то" - альтернатива самому писать midle, буду пробовать Mule.
"Потом его выложили в виде статьи." - плюсанул.
"отсутствие инфы по коннектору" - смотреть на сколько сложно самому написать, язык, API, тесты.
11. 8095_tores 58 19.11.21 14:05 Сейчас в теме
(10)
смотреть на сколько сложно самому написать, язык, API, тесты.


не. просто в AnypointStudio - он может работать.
а в проде - упасть.
при чем если в 3.9 есть возможность использовать OpenSource движок прям в AnypointStudio, то в 4.2 - такой возможности нет.
Оставьте свое сообщение