Postman для аналитика — практическая работа с API

Урок 8 из 8

Урок 07.08: Postman для аналитика — практическая работа с API

Цель урока

Научиться использовать Postman как основной инструмент для тестирования, отладки и документирования API. Пройти полный цикл работы аналитика: от импорта OpenAPI/SOAP-контракта до создания коллекции, настройки окружений, написания скриптов проверки и передачи коллекции в репозиторий. Особый фокус: реальные сценарии аналитика, а не «как нажать кнопку Send».


Ключевые понятия

Термин Определение
Collection (коллекция) Группа API-запросов с общей структурой — аналог «папки проекта»
Environment (окружение) Набор переменных (URL, токен, ID), переключаемых между dev/staging/prod
Variable (переменная) {{baseUrl}}, {{token}} — динамические значения, подставляемые в запрос
Pre-request Script JavaScript-скрипт, выполняемый до отправки запроса (например, установка токена)
Test Script JavaScript-скрипт, выполняемый после получения ответа (проверка статуса, тела)
Runner Запуск всей коллекции или её части последовательно
Newman CLI-версия Postman для запуска коллекций в CI/CD (без графического интерфейса)
Mock Server Эмуляция API на основе OpenAPI-спецификации (когда бэкенд ещё не готов)
Interceptor / Proxy Перехват трафика из браузера или мобильного приложения
History История всех отправленных запросов (можно сохранить в коллекцию)

1. Postman — рабочее место аналитика

1.1. Почему Postman, а не Swagger UI?

Задача Swagger UI Postman
Быстро «потыкать» API ✅ Лучше всего (встроенный Try it out) ⚠️ Нужно импортировать
Группировка запросов по сценариям ❌ Только по эндпоинтам ✅ Коллекции + папки
Переключение между dev/staging/prod ❌ Только 1 URL из OpenAPI ✅ Окружения (переменные)
Работа с SOAP ⚠️ Частично (через REST) ✅ Заголовок SOAPAction + XML Body
Pre-request скрипты (авторизация) ❌ Нет ✅ JavaScript перед запросом
Автоматические тесты ❌ Нет ✅ Test Scripts + Chai Assertions
Запуск в CI/CD ❌ Нет ✅ Newman
Mock-сервер ❌ Нет ✅ Postman Mock Server
Сохранение истории ⚠️ Временно ✅ History + сохранение в коллекцию
Командная работа ❌ Нет (одна спецификация) ✅ Workspaces, Team Collections

Вывод: Swagger UI — для быстрого ознакомления с API (Try it out). Postman — для систематической работы аналитика: коллекции сценариев, окружения, тесты, передача команде.

1.2. Аналогия: Postman — это «инструментальный ящик» аналитика

REST API — это меню ресторана (что можно заказать)
OpenAPI — это меню с технологическими картами (как готовить)
SOAP WSDL — это контракт с курьерской службой

Postman — это ваш НОЖ и РАЗДЕЛОЧНАЯ ДОСКА:
  - Коллекция = набор рецептов (сценариев)
  - Окружение = разные кухни (dev, staging, prod)
  - Переменные = ингредиенты (token, baseUrl, orderId)
  - Тесты = дегустация (проверка, что блюдо съедобно)

1.3. Когда аналитик использует Postman — реальные сценарии

Сценарий Что делает аналитик
Проверка OpenAPI-контракта Импортирует OpenAPI → проверяет: все ли эндпоинты работают, правильные ли статус-коды, форматы ответов
Тестирование SOAP-интеграции Настраивает POST + XML Body + SOAPAction → проверяет SOAP Fault
Подготовка данных для тестирования Через API создаёт тестовые сущности (задачи, пользователей) → чтобы тестировщик мог работать с данными
Демонстрация заказчику Показывает: «вот так API работает сейчас. Видите, задача создаётся, возвращается 201»
Отладка ошибки интеграции Копирует неудачный запрос от разработчика → запускает в Postman → анализирует ответ
Коллекция для команды Собирает все эндпоинты в коллекцию, раскладывает по папкам, добавляет описания → экспортирует в Git
Проверка безопасности Пробует: что будет, если не передать токен (401?), неверный токен (403?), SQL-инъекцию

2. Collections и Environments — база работы

2.1. Структура коллекции (Collection)

Хорошая коллекция аналитика выглядит так:

📁 Task Manager API (коллекция)
│
├── 🏠 Auth
│   ├── POST Register          # Регистрация пользователя
│   └── POST Login             # Получение JWT-токена
│
├── 📋 Tasks
│   ├── GET All Tasks          # Список с фильтрацией
│   ├── GET Task by ID         # Получить задачу
│   ├── POST Create Task       # Создать задачу
│   ├── PATCH Update Status    # Сменить статус
│   └── DELETE Delete Task     # Удалить задачу
│
├── 👥 Users
│   ├── GET Profile            # Профиль текущего пользователя
│   └── GET All Users          # Список пользователей
│
├── 💬 Comments
│   ├── GET Task Comments      # Комментарии задачи
│   └── POST Add Comment       # Добавить комментарий
│
└── 📊 Reports
    └── GET Task Statistics     # Статистика по задачам

Правила хорошей коллекции:

Правило Пример
✅ Папки по ресурсам Tasks, Users, Auth
✅ Названия запросов — глагол + сущность GET All Tasks, POST Create Task
✅ Описание каждого запроса Что делает, какие параметры
✅ Примеры тел запросов Pre-filled JSON
✅ Переменные вместо жёстких значений {{baseUrl}}/tasks/{{taskId}}
✅ Pre-request Script для токена Автоматически устанавливает {{token}}
✅ Test Scripts для проверок Проверяет статус, тип ответа

2.2. Окружения (Environments)

Окружение — это набор переменных, которые подставляются в коллекцию.

Пример окружения «Development»:

{
  "baseUrl": "http://localhost:8080/api/v1",
  "token": "",
  "taskId": "",
  "userId": "",
  "limit": 10
}

Пример окружения «Staging»:

{
  "baseUrl": "https://staging-api.taskmanager.com/api/v1",
  "token": "",
  "taskId": "",
  "userId": "",
  "limit": 20
}

Пример окружения «Production»:

{
  "baseUrl": "https://api.taskmanager.com/api/v1",
  "token": "",
  "taskId": "",
  "userId": "",
  "limit": 50
}

Как работает подстановка:

Запрос в коллекции:   GET {{baseUrl}}/tasks/{{taskId}}?limit={{limit}}
Окружение Dev:        baseUrl = http://localhost:8080/api/v1, taskId = 42, limit = 10
Реальный URL:         GET http://localhost:8080/api/v1/tasks/42?limit=10

Типы переменных в Postman:

Область видимости Приоритет Когда использовать
Global 4 (низший) Статические значения, общие для всех коллекций (например, apiVersion)
Environment 3 Разные для dev/staging/prod (например, baseUrl)
Collection 2 Общие для одной коллекции (например, baseUrl, если коллекция самодостаточна)
Data 1 Из CSV/JSON при запуске Runner (для тестовых данных)
Local 5 (высший) Внутри одного запроса/скрипта (через pm.variables.set())

2.3. Pre-request Script: автоматическая авторизация

Самый частый сценарий: перед каждым запросом нужно установить JWT-токен.

Pre-request Script для коллекции (Collection → Pre-request Script):

// Если токен в окружении пуст или истекает — выполнить login
const token = pm.environment.get("token");

if (!token || token === "") {
    console.log("Token not found — executing login...");
    
    pm.sendRequest({
        url: pm.environment.get("baseUrl") + "/auth/login",
        method: "POST",
        header: {
            "Content-Type": "application/json"
        },
        body: {
            mode: "raw",
            raw: JSON.stringify({
                email: pm.environment.get("testUserEmail"),
                password: pm.environment.get("testUserPassword")
            })
        }
    }, function (err, response) {
        if (!err) {
            const newToken = response.json().token;
            pm.environment.set("token", newToken);
            console.log("Token obtained:", newToken);
        } else {
            console.error("Login failed:", err);
        }
    });
}

Что это даёт:

  • При запуске любого запроса из коллекции токен проверяется
  • Если токена нет — автоматически выполняется POST /auth/login
  • Полученный токен сохраняется в переменную {{token}}
  • Все запросы используют Authorization: Bearer {{token}}

2.4. Collection Variables — «секреты» коллекции

Переменные коллекции удобны для значений, которые не должны меняться между окружениями:

📋 Collection Variables:
   ┌─────────────────────┬──────────────────────────────────┐
   │ Variable            │ Initial Value                    │
   ├─────────────────────┼──────────────────────────────────┤
   │ appName             │ Task Manager API                 │
   │ apiVersion          │ v1                               │
   │ supportedStatuses   │ To Do,In Progress,Testing,Done   │
   │ schemaVersion       │ 1.2.0                            │
   └─────────────────────┴──────────────────────────────────┘

3. Импорт OpenAPI-спецификации

3.1. Как импортировать

У аналитика есть OpenAPI-спецификация (YAML/JSON). Нужно получить коллекцию Postman.

Postman → Import → File (выбрать .yaml/.json)
         → Import → Link (указать URL спецификации)
         → Import → Raw Text (вставить содержимое)

Что Postman делает автоматически:

Исходный OpenAPI Результат в Postman
openapi: 3.1.0 Определяет версию
servers: Создаёт переменную окружения baseUrl
paths: /tasks Папка в коллекции «Tasks»
paths: /tasks get Запрос «GET All Tasks»
paths: /tasks/{taskId} Запрос «GET Task by ID» (с path-параметром)
components/schemas (не импортируются напрямую, но используются в примерах)
securitySchemes BearerAuth Настраивает Authorization: Bearer {{token}}

3.2. Что проверить после импорта (чек-лист аналитика)

Проверка Если проблема Решение
1 Переменная baseUrl создалась? Нет в окружении Создать вручную из servers
2 Все эндпоинты импортировались? Пропущен эндпоинт Проверить OpenAPI на ошибки
3 Path-параметры (:taskId) корректны? Параметр не подставился Ручное исправление: :id{{id}}
4 Query-параметры отобразились? Нет в Params Добавить вручную
5 Примеры тел запросов заполнены? Пустое тело Взять из example в OpenAPI
6 Аутентификация настроена? Нет заголовка Добавить Authorization: Bearer {{token}}
7 Описания (description) эндпоинтов видны? Нет Скопировать из OpenAPI вручную

3.3. Пример: импорт из OpenAPI → что получилось

OpenAPI (фрагмент):

paths:
  /tasks/{taskId}:
    get:
      operationId: getTaskById
      summary: "Получить задачу по ID"
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
        - name: include
          in: query
          schema:
            type: string
      responses:
        "200":
          description: "Задача найдена"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "404":
          description: "Задача не найдена"

После импорта в Postman:

📁 Tasks
   └── 🔹 GET Task by ID
       └── Method:          GET
       └── URL:             {{baseUrl}}/tasks/{{taskId}}
       └── Params:
           └── Path:        taskId  →  {{taskId}}  (required)
           └── Query:       include →  (optional)
       └── Headers:
           └── Authorization:  Bearer {{token}}
       └── Pre-request Script:  (автологин, если токен пуст)
       └── Test Scripts:
           └── Status 200 for success
           └── Status 404 for not found
           └── Response time < 2000ms

4. Ручное тестирование REST API

4.1. Настройка запроса: пошагово

┌──────────────────────────────────────────────────────────────┐
│  POST  {{baseUrl}}/tasks              [Send]                │
├──────────────────────────────────────────────────────────────┤
│ Params │ Authorization │ Headers (8) │ Body │ Scripts │ ...  │
├──────────────────────────────────────────────────────────────┤
│ Body: raw (JSON)                                             │
│                                                              │
│ {                                                            │
│   "title": "Настроить CI/CD",                                │
│   "description": "GitHub Actions pipeline",                  │
│   "priority": "High",                                        │
│   "projectId": 1,                                            │
│   "assigneeId": 42,                                          │
│   "deadline": "2026-07-15"                                   │
│ }                                                            │
├──────────────────────────────────────────────────────────────┤
│ Response: 201 Created  (1.2 сек)                             │
├──────────────────────────────────────────────────────────────┤
│ {                                                            │
│   "id": 128,                                                 │
│   "title": "Настроить CI/CD",                                │
│   "status": "To Do",                                         │
│   "createdAt": "2026-06-12T10:30:00Z"                        │
│ }                                                            │
├──────────────────────────────────────────────────────────────┤
│ Tests (1/1) ✓ Status code is 201                             │
└──────────────────────────────────────────────────────────────┘

Вкладки запроса — что делает аналитик:

Вкладка Что настраивает Типичные действия
Params Path- и Query-параметры Устанавливает {{taskId}}, ?status=Done&page=1
Authorization Тип аутентификации Bearer Token → {{token}}
Headers Дополнительные заголовки Content-Type: application/json, X-Request-Id: {{$guid}}
Body Тело запроса JSON, XML (SOAP), form-data, binary
Pre-request Скрипт до запроса Автологин, генерация timestamp
Tests Скрипт после ответа Проверка статуса, тела, времени

4.2. Частая ошибка: Postman «сам» не подставляет пути

URL: {{baseUrl}}/tasks/{{taskId}}

❌ Если переменная taskId не задана — URL станет:
   http://localhost:8080/api/v1/tasks/
   → 404 Not Found (нет ID)

✅ Как настроить:
   1. Задать taskId в окружении: 42
   2. Или в Params → Path Variables → taskId = 42
   3. Или через Pre-request Script: pm.environment.set("taskId", "42")

4.3. Collection Runner — прогон всех сценариев

После того как вы собрали коллекцию, можно запустить Runner:

Postman → Runner → Выбрать коллекцию
                  → Выбрать окружение
                  → Run Order (порядок запросов)
                  → Iterations (сколько раз прогнать)
                  → Delay (задержка между запросами)
                  → Data (CSV/JSON-файл с тестовыми данными)
                  → [Run TaskManager API]

Результат прогона:

┌──────────────────────────────────────────────────────────────┐
│  Run Results: Task Manager API (7 requests, 3 iterations)    │
│                                                              │
│  ✅ POST  Auth / Login            → 200 OK   (3/3 passed)    │
│  ✅ POST  Tasks / Create Task     → 201 OK   (3/3 passed)    │
│  ✅ GET   Tasks / All Tasks       → 200 OK   (3/3 passed)    │
│  ✅ GET   Tasks / Task by ID      → 200 OK   (3/3 passed)    │
│  ✅ PATCH Tasks / Update Status   → 200 OK   (3/3 passed)    │
│  ✅ GET   Tasks / Task Comments   → 200 OK   (3/3 passed)    │
│  ✅ DELETE Tasks / Delete Task    → 204 OK   (3/3 passed)    │
│                                                              │
│  Total: 21/21 passed, 0 failed                               │
│  Average response time: 245ms                                │
└──────────────────────────────────────────────────────────────┘

Что даёт аналитику:

  • Проверка, что все эндпоинты работают
  • Что сценарии проходят последовательно (создали → прочитали → обновили → удалили)
  • Что нет регрессии после изменений бэкенда
  • Можно экспортировать отчёт (HTML/JSON)

5. SOAP в Postman

Postman поддерживает SOAP, но с ограничениями (по сравнению с SoapUI).

5.1. Настройка SOAP-запроса

┌──────────────────────────────────────────────────────────────┐
│  POST  https://api.example.com/soap/taskmanager/v1  [Send]  │
├──────────────────────────────────────────────────────────────┤
│ Body: raw → XML                                              │
│                                                              │
│ <?xml version="1.0" encoding="UTF-8"?>                       │
│ <soap:Envelope                                               │
│   xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"     │
│   xmlns:task="http://www.example.com/taskmanager">           │
│                                                              │
│   <soap:Header/>                                             │
│                                                              │
│   <soap:Body>                                                │
│     <task:CreateTask>                                        │
│       <task:title>Test task from Postman</task:title>        │
│       <task:projectId>1</task:projectId>                     │
│     </task:CreateTask>                                       │
│   </soap:Body>                                               │
│ </soap:Envelope>                                             │
├──────────────────────────────────────────────────────────────┤
│ Headers:                                                     │
│   Content-Type: text/xml; charset=utf-8  (SOAP 1.1)         │
│   SOAPAction: "http://www.example.com/taskmanager/CreateTask"│
│   (или Content-Type: application/soap+xml для SOAP 1.2)     │
└──────────────────────────────────────────────────────────────┘

5.2. Postman vs SoapUI для SOAP

Возможность Postman SoapUI
Импорт WSDL ❌ Не умеет ✅ Авто-генерация запросов
Формирование Envelope ❌ Ручной XML ✅ Автоматическое
Namespace-менеджмент ❌ Ручной ✅ Автоматический
SOAP Action ✅ Ручной заголовок ✅ Автоматический
WS-Security ❌ Нет поддержки ✅ Настройка UsernameToken
Проверка XPath ⚠️ Через Test Scripts ✅ Встроенные Assertions
Mock SOAP Server ❌ Нет ✅ Да
Load Testing ❌ Ограничен ✅ Встроенный

Вывод для аналитика:

  • Если есть WSDL и нужна серьёзная работа с SOAP → SoapUI
  • Если нужно быстро «пощупать» SOAP-запрос или один раз проверить → Postman
  • Постман не заменяет SoapUI для SOAP, но удобен, когда SOAP — малая часть работы

5.3. Pre-request Script для WS-Security (UsernameToken)

Если SOAP-сервис требует WS-Security, можно сгенерировать UsernameToken в Pre-request Script:

// Pre-request Script: генерация WS-Security UsernameToken
const username = pm.environment.get("soapUsername");
const password = pm.environment.get("soapPassword");
const nonce = CryptoJS.lib.WordArray.random(16).toString(CryptoJS.enc.Base64);
const created = new Date().toISOString().replace(/\.\d{3}/, '');
const passwordDigest = CryptoJS.SHA256(nonce + created + password)
    .toString(CryptoJS.enc.Base64);

pm.environment.set("wsseUsername", username);
pm.environment.set("wssePasswordDigest", passwordDigest);
pm.environment.set("wsseNonce", nonce);
pm.environment.set("wsseCreated", created);

6. Test Scripts — автоматическая проверка ответа

6.1. Стандартный набор проверок для аналитика

Postman использует библиотеку Chai (BDD-стиль) с pm.expect().

Шаблон Tests для любого запроса:

// 1. Статус-код
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

// 2. Время ответа
pm.test("Response time < 2000 ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(2000);
});

// 3. Content-Type
pm.test("Content-Type is JSON", function () {
    pm.response.to.have.header("Content-Type", "application/json; charset=utf-8");
});

// 4. Тело ответа не пустое
pm.test("Response body is not empty", function () {
    pm.response.to.have.body();
});

6.2. Проверки для конкретных эндпоинтов

POST Create Task (должен вернуть 201 + Task):

pm.test("Status 201 Created", () => pm.response.to.have.status(201));

const jsonData = pm.response.json();

pm.test("Task has required fields", () => {
    pm.expect(jsonData).to.have.property("id");
    pm.expect(jsonData).to.have.property("title");
    pm.expect(jsonData).to.have.property("status");
    pm.expect(jsonData).to.have.property("createdAt");
});

pm.test("Status is 'To Do'", () => {
    pm.expect(jsonData.status).to.eql("To Do");
});

pm.test("ID is integer", () => {
    pm.expect(jsonData.id).to.be.a("number");
});

// Сохраняем ID для следующих запросов
pm.environment.set("taskId", jsonData.id);

GET Task by ID (должен вернуть 200 + ту же задачу):

pm.test("Status 200 OK", () => pm.response.to.have.status(200));

const jsonData = pm.response.json();

pm.test("Task matches expected ID", () => {
    pm.expect(jsonData.id).to.eql(parseInt(pm.environment.get("taskId")));
});

pm.test("Response matches schema", () => {
    const schema = {
        type: "object",
        required: ["id", "title", "status", "createdAt"],
        properties: {
            id: { type: "number" },
            title: { type: "string" },
            status: { type: "string", enum: ["To Do", "In Progress", "Testing", "Done", "Blocked"] },
            createdAt: { type: "string" }
        }
    };
    pm.response.to.have.jsonSchema(schema);
});

PATCH Update Status (проверка идемпотентности):

pm.test("Status 200 OK", () => pm.response.to.have.status(200));

const jsonData = pm.response.json();

pm.test("Status changed to 'In Progress'", () => {
    pm.expect(jsonData.status).to.eql("In Progress");
});

// Проверка: второй PATCH с тем же статусом не меняет updatedAt (идемпотентность)
pm.test("Idempotency: same status does not change updatedAt", () => {
    const previousUpdatedAt = pm.environment.get("taskUpdatedAt");
    if (previousUpdatedAt) {
        // Если уже обновляли — проверить, что updatedAt не изменился
        pm.expect(jsonData.updatedAt).to.eql(previousUpdatedAt);
    } else {
        // Первый раз — сохраняем
        pm.environment.set("taskUpdatedAt", jsonData.updatedAt);
    }
});

DELETE Delete Task (должен вернуть 204 No Content):

pm.test("Status 204 No Content", () => pm.response.to.have.status(204));

pm.test("Response body is empty", () => {
    pm.expect(pm.response.body).to.be.empty;
});

// Проверка: повторный DELETE возвращает 404
pm.test("Second delete returns 404 (idempotency)", () => {
    // Эта проверка запускается ДО первой отправки, поэтому делаем 2 запроса
    pm.sendRequest({
        url: pm.environment.get("baseUrl") + "/tasks/" + pm.environment.get("taskId"),
        method: "DELETE",
        header: { "Authorization": "Bearer " + pm.environment.get("token") }
    }, function (err, response) {
        pm.expect(response.code).to.eql(404);
    });
});

6.3. Проверка SOAP-ответа

pm.test("SOAP Fault not present", () => {
    // Если в ответе есть SOAP Fault — тест не пройден
    const hasFault = pm.response.text().includes("<soap:Fault>") || 
                     pm.response.text().includes("<soap12:Fault>");
    pm.expect(hasFault).to.be.false;
});

pm.test("Response has CreateTaskResponse", () => {
    pm.expect(pm.response.text()).to.include("CreateTaskResponse");
});

// Извлечение taskId из XML через регулярное выражение
pm.test("Task ID extracted from SOAP response", () => {
    const match = pm.response.text().match(/<task:taskId>(\d+)<\/task:taskId>/);
    if (match && match[1]) {
        pm.environment.set("taskId", parseInt(match[1]));
    }
    pm.expect(match).to.not.be.null;
});

6.4. Чек-лист тестов для каждого эндпоинта

Эндпоинт Проверки
GET /tasks 200, тело — массив, пагинация {data, pagination}, каждый объект — Task
GET /tasks/{id} 200 (есть), 404 (нет), тело — Task, поля соответствуют схеме
POST /tasks 201, тело — Task с id, status = "To Do", обязательные поля
POST /tasks (invalid) 422, тело — ErrorResponse с code + message
PATCH /tasks/{id}/status 200, статус изменился, идемпотентность
DELETE /tasks/{id} 204 (первый), 404 (второй), тело пустое
POST /auth/login 200, тело — {token, user}, token — непустая строка
POST /auth/login (bad pass) 401, тело — ErrorResponse
GET /tasks (no auth) 401, тело — ErrorResponse

7. Newman — запуск коллекций в CI/CD

7.1. Что такое Newman

Newman — это консольная (CLI) версия Postman. Она позволяет запускать коллекции:

  • В CI/CD (GitLab CI, Jenkins, GitHub Actions)
  • На сервере (Linux без GUI)
  • В автоматических тестах ночью (nightly build)

7.2. Установка и запуск

# Установка (требуется Node.js)
npm install -g newman

# Запуск коллекции
newman run "Task Manager API.postman_collection.json" \
  --environment "Staging.postman_environment.json" \
  --reporters cli,htmlextra \
  --reporter-htmlextra-export ./reports/api-test-report.html

7.3. Что видит аналитик в отчёте Newman

Newman генерирует HTML-отчёт с результатами:

┌─────────────────────────────────────────────────────────────┐
│  Newman Report — Task Manager API                           │
│  Environment: Staging                                       │
│  Date: 2026-06-12T10:30:00Z                                 │
│                                                              │
│  ┌───────┬────────────────────────────────┬────────┬───────┐│
│  │ Status│ Request                        │ Time   │ Test  ││
│  ├───────┼────────────────────────────────┼────────┼───────┤│
│  │ ✅    │ POST Auth / Login              │ 450ms  │ 3/3   ││
│  │ ✅    │ POST Tasks / Create Task       │ 320ms  │ 4/4   ││
│  │ ✅    │ GET Tasks / All Tasks          │ 210ms  │ 3/3   ││
│  │ ✅    │ GET Tasks / Task by ID         │ 180ms  │ 3/3   ││
│  │ ✅    │ PATCH Tasks / Update Status    │ 250ms  │ 4/4   ││
│  │ ✅    │ DELETE Tasks / Delete Task     │ 100ms  │ 3/3   ││
│  ├───────┼────────────────────────────────┼────────┼───────┤│
│  │       │ Total: 6/6 passed, 0 failed   │ 1.5s   │ 20/20 ││
│  └───────┴────────────────────────────────┴────────┴───────┘│
│                                                              │
│  Failed tests: —                                              │
│  Warnings:                                                   │
│    • PATCH Tasks / Update Status: avg time 450ms > 300ms     │
└─────────────────────────────────────────────────────────────┘

7.4. Пример интеграции в CI/CD (GitHub Actions)

name: API Tests

on:
  pull_request:
    paths:
      - 'backend/**'

jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Start backend
        run: docker-compose up -d backend
      
      - name: Install Newman
        run: npm install -g newman newman-reporter-htmlextra
      
      - name: Run API tests
        run: |
          newman run collections/task-manager-api.json \
            --environment collections/staging-env.json \
            --reporters cli,htmlextra \
            --reporter-htmlextra-export reports/api-test-report.html
      
      - name: Upload report
        uses: actions/upload-artifact@v4
        with:
          name: api-test-report
          path: reports/api-test-report.html

8. Mock Server — API без бэкенда

8.1. Когда это нужно аналитику

Сценарий Без Mock Server С Mock Server
Фронтенд готов, бэкенд — нет Фронтенд ждёт Фронтенд работает против Mock
Нужно показать API заказчику «Вот OpenAPI, читайте» «Вот интерактивный прототип, нажимайте кнопки»
Зависимый сервис ещё не готов Интеграция заблокирована Можно тестировать изолированно
Нужны тестовые сценарии (ошибки) Трудно воспроизвести Mock возвращает нужную ошибку по требованию

8.2. Как создать Mock Server в Postman

# Способ 1: Из коллекции
# Postman → Collection → ... → Mock Server → Create New Mock Server
# Postman создаёт URL: https://xxxx.mock.pstmn.io

# Способ 2: Из OpenAPI (без Postman-коллекции)
# Postman → New → Mock Server → Upload OpenAPI → Create

Примеры ответов Mock Server:

// Запрос: GET {{mockUrl}}/tasks/42
// Ответ (на основе example из OpenAPI или сохранённого примера в коллекции):
{
    "id": 42,
    "title": "Mock Task",
    "status": "To Do",
    "priority": "Medium",
    "createdAt": "2026-06-12T10:00:00Z"
}

// Запрос: GET {{mockUrl}}/tasks/999
// Ответ (на основе сохранённого примера 404):
{
    "error": {
        "code": "NOT_FOUND",
        "message": "Task with id 999 not found"
    }
}

8.3. Примеры (Response Examples) — ключ к Mock Server

Чтобы Mock Server возвращал разные ответы на разные запросы, нужно сохранить Example Responses в коллекции:

📁 Tasks
   └── 🔹 GET Task by ID
       ├── 📝 Example: Success (200)    ← ответ для существующей задачи
       │   { "id": 42, "title": "...", "status": "To Do" }
       └── 📝 Example: Not Found (404)  ← ответ для несуществующей задачи
           { "error": { "code": "NOT_FOUND", ... } }

Postman Mock Server анализирует:

  • Method (GET/POST/...)
  • URL path (/tasks/42 vs /tasks/999)
  • Query params (?status=done)
  • Request body (для POST/PATCH/PUT)
  • Выбирает подходящий Example

9. Пример рабочего процесса аналитика в Postman

9.1. Полный цикл: от контракта до коллекции в Git

┌────────────────────────────────────────────────────────────────┐
│  ЭТАП 1: ПОЛУЧЕНИЕ КОНТРАКТА                                  │
│                                                                 │
│  Разработчик или партнёр передаёт:                             │
│   • OpenAPI YAML (для REST) или URL WSDL (для SOAP)           │
│   • Или: черновик на бумаге                                    │
│                                                                 │
└────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌────────────────────────────────────────────────────────────────┐
│  ЭТАП 2: СОЗДАНИЕ КОЛЛЕКЦИИ                                   │
│                                                                 │
│  Действия аналитика:                                           │
│   1. Postman → Import → OpenAPI файл                         │
│   2. Проверить: все ли эндпоинты импортированы                  │
│   3. Разложить по папкам (Auth, Tasks, Users, Comments)        │
│   4. Добавить описания (description) к запросам                │
│   5. Создать окружения (Dev, Staging, Prod)                    │
│   6. Настроить Pre-request Script (автологин, токен)           │
│   7. Написать Test Scripts для каждого эндпоинта               │
│   8. Сохранить примеры ответов (Example Responses)             │
│   9. Экспортировать коллекцию и окружение в JSON               │
│   10. Закоммитить в репозиторий (например, в /collections/)    │
│                                                                 │
└────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌────────────────────────────────────────────────────────────────┐
│  ЭТАП 3: ТЕСТИРОВАНИЕ                                          │
│                                                                 │
│  1. Ручной прогон ключевых сценариев (Positive + Negative)     │
│  2. Runner: прогон всей коллекции (3-5 итераций)               │
│  3. Если нашли баг:                                            │
│     • Зафиксировать запрос (Save Response)                     │
│     • Приложить к баг-репорту (Export → Share)                 │
│  4. Исправления в контракте → обновить OpenAPI → переимпорт   │
│                                                                 │
└────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌────────────────────────────────────────────────────────────────┐
│  ЭТАП 4: ПЕРЕДАЧА КОМАНДЕ                                     │
│                                                                 │
│  Кому:                                                         │
│   • Тестировщикам (они используют коллекцию для тест-кейсов)   │
│   • Фронтенд-разработчикам (проверяют формат ответов)          │
│   • Бэкенд-разработчикам (видят ожидаемое поведение)          │
│                                                                 │
│  Формат:                                                       │
│   • JSON-файлы коллекции + окружения в Git                     │
│   • Ссылка на Postman Workspace (Team)                         │
│   • Newman-команда для CI/CD                                   │
│                                                                 │
└────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌────────────────────────────────────────────────────────────────┐
│  ЭТАП 5: ПОДДЕРЖКА (при изменениях API)                       │
│                                                                 │
│  1. Разработчик меняет API → обновляет OpenAPI                 │
│  2. Аналитик: Postman → Import (Update existing)              │
│  3. Проверить: какие эндпоинты изменились                      │
│  4. Обновить Test Scripts под новое поведение                  │
│  5. Прогнать Runner → убедиться, что регрессии нет             │
│  6. Закоммитить обновлённую коллекцию                          │
│                                                                 │
└────────────────────────────────────────────────────────────────┘

9.2. Что экспортировать в Git

📁 collections/
   ├── Task Manager API.postman_collection.json    # Коллекция
   ├── Dev.postman_environment.json                # Окружение Dev
   ├── Staging.postman_environment.json             # Окружение Staging
   └── Production.postman_environment.json          # Окружение Prod (без sensitive-данных!)

Важно: Не коммитить токены и пароли в Git. Используйте initial значения, а current — через CI/CD переменные или .env:

{
  "key": "token",
  "value": "",
  "type": "secret",
  "enabled": true
}

9.3. Полезные динамические переменные Postman

Переменная Значение Пример использования
{{$guid}} Случайный UUID Идемпотентность: Idempotency-Key: {{$guid}}
{{$timestamp}} Unix timestamp в секундах ?since={{$timestamp}}
{{$isoTimestamp}} ISO 8601 дата-время Поле createdAt в теле запроса
{{$randomEmail}} Случайный email Регистрация тестового пользователя
{{$randomInt}} Случайное целое ID несуществующего ресурса
{{$randomUUID}} UUID (версия 4) Correlation ID

Пример регистрации нового пользователя с динамическим email:

{
    "name": "Test User",
    "email": "{{$randomEmail}}",
    "password": "TestPass123!"
}

Каждый запуск Postman подставит новый email → не будет конфликта дубликатов.


10. Postman Workspaces — командная работа

10.1. Типы Workspaces

Тип Для кого Особенность
Personal Вы один Личные эксперименты
Team Вся команда Коллекции, окружения, история — общие
Private Только приглашённые Для заказчика или партнёра (ограниченный доступ)
Public Все Публичные API (можно ссылаться в документации)

10.2. Что даёт Team Workspace

  • Единая коллекция — все видят актуальные запросы
  • Не нужно пересылать JSON-файлы
  • История изменений (кто, что, когда изменил)
  • Комментарии к запросам
  • Activity log

Вопросы для самопроверки

Базовый уровень

  1. Чем Postman отличается от Swagger UI? В каких сценариях каждый удобнее?
  2. Что такое Collection, Environment, Variable в Postman? Как они связаны?
  3. Как импортировать OpenAPI-спецификацию в Postman? Что нужно проверить после импорта?
  4. Зачем аналитику писать Test Scripts в Postman? Приведите 3 примера проверок.
  5. Что такое Newman и зачем он нужен в CI/CD?

Продвинутый уровень

  1. Chain запросов: У вас в коллекции 3 запроса: Login → Create Task → Get Task by ID. Как передать taskId из второго запроса в третий?
  2. SOAP vs REST в Postman: Какие ограничения Postman для SOAP? В каком случае вы выберете SoapUI вместо Postman?
  3. Mock Server: Заказчик хочет увидеть, как будет работать API через 2 недели (бэкенд ещё не готов). Что вы сделаете?
  4. Pre-request Script: Напишите скрипт, который перед каждым запросом проверяет, не истёк ли JWT-токен, и если истёк — выполняет автоматический login.
  5. Командная работа: Как организовать работу с Postman в команде из 10 человек так, чтобы коллекция всегда была актуальной, а токены и пароли не попадали в Git?

Практическое задание

Задание 1. Создание окружений (2 балла)

Создайте три окружения Postman для Task Manager API:

Окружение baseUrl limit Аутентификация
Development http://localhost:8080/api/v1 10 test@example.com / TestPass123
Staging https://staging-api.taskmanager.com/api/v1 25 test@example.com / TestPass123
Production https://api.taskmanager.com/api/v1 50 — (токен не хранить)

1.1. (1 балл) Опишите в Markdown-таблице, какие переменные в каждом окружении и их значения. 1.2. (1 балл) Объясните, почему токен не должен храниться в Production-окружении. Как правильно организовать аутентификацию в Production?

Задание 2. OpenAPI → Коллекция (3 балла)

Возьмите OpenAPI-спецификацию из урока 07.02 (или любую существующую OpenAPI 3.x для системы задач).

2.1. (1 балл) Импортируйте её в Postman. Перечислите, что импортировалось корректно, а что пришлось донастроить вручную. 2.2. (1 балл) Разложите запросы по папкам (Auth, Tasks, Users, Comments). Добавьте описание к каждой папке. 2.3. (1 балл) Настройте Pre-request Script для автоматической авторизации (если нет токена — выполнить POST /auth/login).

Задание 3. Test Scripts (3 балла)

Напишите Test Scripts для трёх эндпоинтов:

3.1. POST /tasks (Create Task) — проверки:

  • Статус-код 201
  • Content-Type: application/json
  • Тело содержит id (integer), title, status="To Do", createdAt (date-time)
  • Сохранить taskId в переменную окружения

3.2. GET /tasks/{taskId} (Get Task) — проверки:

  • Статус-код 200
  • Тело соответствует схеме Task
  • id совпадает с taskId из окружения
  • Время ответа < 1500ms

3.3. DELETE /tasks/{taskId} (Delete Task) — проверки:

  • Статус-код 204
  • Тело пустое
  • Повторный DELETE возвращает 404

Задание 4. Newman — CI/CD (1 балл)

Напишите команду Newman для запуска коллекции Task Manager API:

  • Файл коллекции: collections/task-manager-api.json
  • Окружение: collections/staging-env.json
  • Формат отчёта: cli + htmlextra
  • Путь для отчёта: ./reports/api-test-report.html
  • Задержка между запросами: 500ms

Задание 5. Рабочий процесс аналитика (1 балл)

К вам пришёл разработчик и сказал: «Я изменил API — добавил новый эндпоинт PATCH /tasks/{taskId}/assign (назначить исполнителя) и удалил поле description из ответа GET /tasks/{taskId}».

Опишите пошагово, что вы сделаете как аналитик в Postman:

  1. Как узнаете об изменениях?
  2. Как обновите коллекцию?
  3. Как проверите, что старые сценарии не сломались?
  4. Как передадите коллекцию тестировщикам?

Критерии оценки

Задание Баллы
Задание 1: Создание окружений 2
Задание 2: OpenAPI → Коллекция 3
Задание 3: Test Scripts 3
Задание 4: Newman — CI/CD 1
Задание 5: Рабочий процесс аналитика 1
Итого 10

Справочные материалы

Динамические переменные Postman

Переменная Формат Пример
{{$guid}} XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 3f5c8e1a-2b4d-4a7f-9c6e-1d2b3c4d5e6f
{{$timestamp}} Unix epoch seconds 1718171400
{{$isoTimestamp}} ISO 8601 2026-06-12T10:30:00.000Z
{{$randomEmail}} Email user42@example.com
{{$randomInt}} 0–1000 847
{{$randomUUID}} UUID v4 c4e1f3a8-7b2d-4e6f-9a1c-3d5b7e8f2a0c

Полезные сниппеты Test Scripts

// Проверка статуса
pm.test("Status is 200", () => pm.response.to.have.status(200));

// Проверка заголовка
pm.test("Content-Type is JSON", () => {
    pm.response.to.have.header("Content-Type", "application/json");
});

// Проверка тела (свойство существует)
pm.test("Body has id", () => {
    pm.expect(pm.response.json()).to.have.property("id");
});

// Проверка типа поля
pm.test("id is number", () => {
    pm.expect(pm.response.json().id).to.be.a("number");
});

// Проверка массива
pm.test("Response is array of tasks", () => {
    const tasks = pm.response.json().data;
    pm.expect(tasks).to.be.an("array");
    pm.expect(tasks.length).to.be.at.least(1);
    tasks.forEach(task => {
        pm.expect(task).to.have.property("id");
        pm.expect(task).to.have.property("title");
    });
});

// Проверка JSON Schema
pm.test("Response matches schema", () => {
    const schema = { type: "object", required: ["id", "title", "status"] };
    pm.response.to.have.jsonSchema(schema);
});

// Сохранение значения из ответа
const id = pm.response.json().id;
pm.environment.set("taskId", id);

Быстрые ссылки

Ресурс URL
Postman Download https://www.postman.com/downloads/
Newman CLI https://github.com/postmanlabs/newman
Postman Mock Servers https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/
Postman Sandbox API https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/
Newman HTML Reporter https://github.com/postmanlabs/newman-reporter-htmlextra
Postman Collection Format https://schema.postman.com/

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

🖼️ Схема и инфографика

🎬 Видео-лекция

🎬 API и интеграции

📄 Дополнительные материалы (PDF)

📄API Integration Blueprints
Скачать
Спросить ИИ