Введение в Postman / Хабр

Введение

image
1 — коллекция, 2 — папка, 3 — запрос

Главные понятия, которыми оперирует Postman это Collection (коллекция) на верхнем уровне, и Request (запрос) на нижнем. Вся работа начинается с коллекции и сводится к описанию вашего API с помощью запросов. Давайте рассмотрим подробнее всё по порядку.

Получение ответа для основного запроса

pm.response.json(); // в виде json
pm.response.text(); // в виде строки
responseBody; // в виде строки

Ответ доступен только во вкладке “Tests”

Accessing apis with client credentials flow

Client Credentials Flow is a one of the grant types in OAuth 2.0 in which client applications use client_id, client_secret and sometimes a scope in exchange for an access_token to access a protected API resource.

Can we improve it?

Yes. But first, let’s create a few collection variables to store the authorization credentials we need. The trick here is to group all your API requests into a collection. To do this, click the “Collections” menu and then click the symbol as shown in the following:

You can name the collection to whatever you like for as long as it’s meaningful. 😉 For this example, we’re just going to name it as “Weather APIs”. Under the “Authorization” tab of the collection, select OAuth 2. 0 as the type just like in the following:

Clicking the OAuth 2.0 item should present you a new screen. Leave the default values as is for now. We’ll get back to them later.

Next, let’s configure a few local collection variables. Go ahead and switch to the Variables tab and add the following entries:

In the preceding screenshot, we’ve set the issuer, client_id, client_secret and scope values in it’s own variable. Just make sure you replace these values with the correct values you have and then click “Save”.

Tip: Depending on your needs or if you prefer, you can also define them in Global or Environment variables.

Collection

Коллекция — отправная точка для нового API. Можно рассматривать коллекцию, как файл проекта. Коллекция объединяет в себе все связанные запросы. Обычно API описывается в одной коллекции, но если вы желаете, то нет никаких ограничений сделать по-другому. Коллекция может иметь свои скрипты и переменные, которые мы рассмотрим позже.

Collection runner

https://www.youtube.com/watch?v=_uqhc3nTLsI

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

// Следующим выполнится запрос с названием "Create order",
postman.setNextRequest('Create order');

После выполнения всех запросов формируется отчет, который покажет количество успешных и провальных проверок из скриптов “Tests”.

image
Collection Runner

Console

Пользуйтесь консолью для отладки ваших скриптов, и просмотра дополнительной информации по запросам. Консоль работает, как во время запуска одного запроса, так и во время запуска пакета запросов через Runner. Чтобы её открыть, найдите иконку консоли в нижнем левом углу основного экрана приложения:

Creating the pre-request script

Now, switch to the “Pre-request Script” tab in the collection and copy the following scripts:

var tokenCreatedAt = pm.collectionVariables.get("WeatherApi_Token_CreatedAt");

if (!tokenCreatedAt) {
    tokenCreatedAt = new Date(new Date().setDate(new Date().getDate() - 1))
}

var tokenExpiresIn = pm.collectionVariables.get("WeatherApi_Token_ExpiresIn");

if (!tokenExpiresIn) {
    tokenExpiresIn = 5000;
}

var tokenCreatedTime = (new Date() - Date.parse(tokenCreatedAt))

if (tokenCreatedTime >= tokenExpiresIn) {

    console.log("The token has expired. Attempting to request a new token.");

    pm.sendRequest({
        url: pm.variables.get("WeatherApi_AuthorityUrl"),
        method: 'POST',
        header: {
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: {
            mode: 'urlencoded',
            urlencoded: [{
                    key: "client_id",
                    value: pm.collectionVariables.get("WeatherApi_ClientId"),
                    disabled: false
                },
                {
                    key: "client_secret",
                    value: pm.collectionVariables.get("WeatherApi_ClientSecret"),
                    disabled: false
                },
                {
                    key: "scope",
                    value: pm.collectionVariables.get("WeatherApi_Scope"),
                    disabled: false
                },
                {
                    key: "grant_type",
                    value: "client_credentials",
                    disabled: false
                }
            ]
        }
    }, function(error, response) {
        console.log(response.json().access_token);
        
        pm.collectionVariables.set("WeatherApi_Token_CreatedAt", new Date());
        pm.collectionVariables.set("WeatherApi_Jwt", response.json().access_token);

        var expiresIn = response.json().expires_in;
        
        if (expiresIn) {
            tokenExpiresIn = expiresIn * 1000;
        }
        
        pm.collectionVariables.set("WeatherApi_Token_ExpiresIn", tokenExpiresIn);
    });
}

Let’s see what we just did by breaking out the code.

The first thing that we did there was getting the value of WeatherApi_Token_CreatedAt variable. When running the script for the first time, that call will return an empty value because we haven’t set any value for that variable. Let’s take a look at the next code:

if(!tokenCreatedAt){
  tokenCreatedAt = new Date(new Date().setDate(new Date().getDate()-1)) 
}

The preceding code initializes the tokenCreatedAt variable with the previous day. This is to ensure that we issue a request for getting a new access token on the first run.  Same goes for the handling the tokenExpiresIn value:

if(!tokenExpiresIn){
    tokenExpiresIn = 5000; 
}

The preceding code initializes the tokenExpiresIn value to 5 seconds when the WeatherApi_Token_ExpiresIn is empty.

Is there a way to fully automate this?

You bet! They key to full automation is writing a script. Fortunately, Postman has a feature that allows us to write scripts using JavaScript to perform custom actions before a request is sent. This is called “Pre-request Script”.

Before we begin writing the scripts for automation, let’s add the following new collection variables:

The preceding screenshot shows the following newly added variables:

  • WeatherApi_Token_CreatedAt – Holds the token generation date.
  • WeatherApi_Token_ExpiresIn – Holds the token expiry expressed in milliseconds.
  • WeatherApi_Jwt – Holds the value of access_token.

We’ll leave the variable values empty as we will be populating them dynamically from the script that we are going to create next.

Learning the basic

If you’ve been using Postman to peform basic Web API testing, feel free to skip this part. But if haven’t tried using Postman before and would like to know how to use it to test your Web APIs, then keep reading as I’ll show you how we can easily setup the configuration for you to be able to test protected Web APIs.

Postman is really a handy tool to test API’s without having you to create a UI and it’s absolutely free. In fact, it offers a ton of features that makes it a power tool for managing and testing APIs. If you haven’t installed it yet, go ahead and download it here.

After downloading, install it in your machine so you can start testing. The following screenshot shows the Postman app running on my machine using v8.0.6 – the latest version as of this time of writing.

Postman

Основное предназначение приложения — создание коллекций с запросами к вашему API. Любой разработчик или тестировщик, открыв коллекцию, сможет с лёгкостью разобраться в работе вашего сервиса. Ко всему прочему, Postman позволяет проектировать дизайн API и создавать на его основе Mock-сервер.

Вашим разработчикам больше нет необходимости тратить время на создание “заглушек”. Реализацию сервера и клиента можно запустить одновременно. Тестировщики могут писать тесты и производить автоматизированное тестирование прямо из Postman. А инструменты для автоматического документирования по описаниям из ваших коллекций сэкономят время на ещё одну “полезную фичу”. Есть кое-что и для администраторов — авторы предусмотрели возможность создания коллекций для мониторинга сервисов.

The scenario

Most Web APIs (if not all) are protected with JSON Web Tokens (JWT). In ASP.NET Core, this is done by configuring our Web APIs with a “Bearer” authentication scheme. When our APIs are decorated with the [Authorize] attribute, the requesting clients should provide the access token generated from the Authorization Server and pass it as a Bearer Authorization Header before clients can be granted access to our API endpoints.

Various ways on configuring bearer token generation

The previous approach is is perfectly fine if you are only testing a couple of API endpoints, but when dealing with many endpoints, you should consider automating them as much as possible to improve your productivy.  Let’s see how we can do this in Postman.

Please know that there are many ways on how to setup your automation and this is just one of them.

The first approach is using the a Global Variable feature of Postman. Go ahead and click the “eye” icon as shown in the following:

Alternatively, you can click the “Environments” icon from the left panel:

Clicking whichever icon should display the following dialog:

The preceding screenshot allows us to set global or environment-specific variables.  If you are dealing with multiple environments like (Dev, Test, Stage and Prod), then you may want to consider using the Environment feature to setup environment-specific variables. In this example, we’re just going to use a a global variable to store the bearer token for the sake of simplicity.

Tip: For more information about variables usage and their scopes, see: Understanding Postman Variables

Now,  click “Edit” and from there, you should be able to define whatever variables you need. For this example, we’re going to store the value of access_token value in a variable called AuthTokenVar as shown in the following:

After saving the configuration, the variable AuthTokenVar should be accessible anywhere in your workspace regardless of which environment you’re on. Here’s the updated configuration of the  /weatherforecastrequest using the AuthTokenVar variable.

Переменные

Postman имеет несколько пространств и областей видимости для переменных:

Глобальные переменные и переменные окружения можно создать, если нажать на шестеренку в правом верхнем углу программы. Они существуют отдельно от коллекций. Переменные уровня коллекции создаются непосредственно при редактировании параметров коллекции, а локальные переменные из выполняемых скриптов. Также существуют переменные уровня данных, но они доступны только из Runner, о котором мы поговорим позже.

image[image]
Приоритет пространств переменных (из оф. документации)

Особенностью переменных в Postman является то, что вы можете вставлять их в конструкторе запроса, в URL, в POST параметры, в Cookie, всюду, используя фигурные скобки в качестве плейсхолдера для подстановки.

Получение информации о текущем скрипте

pm.info.eventName; // вернет test или prerequest в зависимости от контекста
pm.info.iteration; // текущая итерация в Runner
pm.info.iterationCount; // общее количество итераций
pm.info.requestName; // название текущего запроса
pm.info.requestId; // внутренний идентификатор запроса

Практика

Так как создание коллекций и запросов в конструкторе не должно вызвать затруднений, практическую часть посвятим написанию скриптов, и рассмотрим как создать цепочку запросов с тестами. Перед началом создайте новую коллекцию, назовите её “Habra”, затем создайте новое окружение под названием “Habra.Env”

Работа со встроенными библиотеками

Документация регламентирует наличие некоторого количества встроенных библиотек, среди которых — tv4 для валидации json, xml2js конвертер xml в json, crypto-js для работы с шифрованием, atob, btoa и др.

// подключение xml2js
var xml2js = require(“xml2js”);
// преобразование простого xml в json объект
xml2js.parseString("<root>Hello xml2js!</root>", function(err, res) {
    console.log(res);
});

Некоторые из библиотек, например, как tv4 не требуют прямого подключения через require и доступны по имени сразу.

Скрипты

“Postman Sandbox” это среда исполнения JavaScript доступная при написании “Pre-request Script” и “Tests” скриптов. “Pre-request Script” используется для проведения необходимых операций перед запросом, например, можно сделать запрос к другой системе и использовать результат его выполнения в основном запросе. “Tests” используется для написания тестов, проверки результатов, и при необходимости их сохранения в переменные.

image
Последовательность выполнения запроса (из оф. документации)

Помимо скриптов на уровне запроса, мы можем создавать скрипты на уровне папки, и, даже, на уровне коллекции. Они называются также — “Pre-request Script” и “Tests”, но их отличие в том, что они будут выполняться перед каждым и после каждого запроса в папке, или, как вы могли догадаться, во всей коллекции.

image
Последовательность выполнения запроса со скриптами папок и коллекций (из оф. документации)

Создание глобального хелпера

В некоторых случаях вам захочется создать функции, которые должны быть доступны во всех запросах. Для этого в первом запросе в секции “Pre-request Script” напишите следующий код:

// создаем и сохраняем хелпер для глобального использования
pm.environment.set("pmHelper", function pmHelper() {
    let helpers = {};

    helpers.usefulMethod = function() {
        console.log(“It is helper, bro!”);
    };

    return helpers;
}   '; pmHelper();');

А в последующих скриптах пользуемся им так:

// получаем объект
var pmHelper = eval(pm.environment.get("pmHelper"));
// вызываем наш метод
pmHelper.usefulMethod();

Это лишь небольшой список полезных команд. Возможности скриптов гораздо шире, чем можно осветить в одной статье. В Postman есть хорошие “Templates”, которые можно найти при создании новой коллекции. Не стесняйтесь подглядывать и изучать их реализацию. А официальная документация содержит ответы на большинство вопросов.

Тестирование или asserts

// с использованием анонимной функции и специальных assert конструкций
pm.test(“Название теста”, function () {
    pm.response.to.be.success;
    pm.expect(“value”).to.be.true;
    pm.expect(“other”).to.equal(“other”);
});
// с использованием простого условия и массива tests
tests[“Название теста”] = (“a” != “b”);
tests[“Название теста 2”] = true;

Управление последовательностью запросов из скрипта

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

// установить следующий запрос
postman.setNextRequest(“Название запроса”); // по названию
postman.setNextRequest(ID); // по идентификатору
// остановить выполнение запросов
postman.setNextRequest(null);

После перехода на следующий запрос Postman возвращается к линейному последовательному выполнению запросов.

Установка и получение переменных

// глобальные переменные
pm.globals.set(“key”, “value”);
pm.globals.get(“key”);

// переменные окружения
pm.environment.set(“key”, “value”);
pm.environment.get(“key”);

// локальные переменные
pm.variables.set(“key”, “value”);
pm.variables.get(“key”); // если нет локальной, будет искать на уровне выше

Шаг 3

Вы могли заметить, что два тестовых скрипта имеют одинаковую проверку формата и статуса:

pm.test("Status is ok, response is json", function () {
    pm.response.to.be.ok;
    pm.response.to.be.json;
});

Пока мы не зашли слишком далеко, давайте исправим эту ситуацию и перенесем эти тесты на уровень коллекции. Откройте редактирование нашей коллекции, и перенесите проверку формата и статуса во вкладку “Tests”, а из запросов их можно удалить. Теперь эти проверки будут автоматически вызываться перед скриптами “Tests” для каждого запроса в коллекции. Таким образом мы избавились от копирования данной проверки в каждый запрос.

Conclusion

In this article we’ve discussed several authorization methods. In terms of authorization, Postman is much more powerful though. OAuth 2.0, Hawk and some more specific authorization methods are left aside today. Well, that’s a nice reason to get back to this topic one day, isn’t it? 🙂

Заключение

Основные плюсы, которые подтолкнули нас к использованию Postman в своём проекте:

Среди минусов можно выделить:

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

P.S.:Основной функционал Postman бесплатен и удовлетворяет ежедневным нуждам, но есть некоторые инструменты с рядом ограничений в бесплатной версии:

Похожее:  Postman: как пользоваться программой для тестирования API, инструкция для начинающих

Добавить комментарий

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