Давайте признаем — ручное тестирование API примерно так же увлекательно, как смотреть, как сохнет краска, и в два раза более подвержено ошибкам. Если вы когда-нибудь ловили себя на том, что в сотый раз кликаете по одним и тем же конечным точкам API, бормоча себе под нос о бессмысленности существования человека, то эта статья — ваше спасение. Мы собираемся создать надёжную автоматизированную систему тестирования API с помощью Postman и Newman, которая сделает вашу жизнь бесконечно проще (а ваши API — бесконечно надёжнее).

Динамичный дуэт: Postman и Newman

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

Postman предоставляет графический интерфейс, где вы создаёте свои API-запросы, пишете тесты и организуете всё в аккуратные коллекции. Newman берёт эти коллекции и запускает их из командной строки, что делает его идеальным для автоматизации, конвейеров CI/CD и впечатления коллег своими навыками DevOps.

Преимущество этого партнёрства заключается в его бесшовном рабочем процессе — вы проектируете и отлаживаете в удобном GUI Postman, а затем развёртываете те же тесты через Newman для непрерывного автоматизированного тестирования.

Настройка среды тестирования

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

Установка Node.js и Newman

Newman работает на Node.js, так что это наша первая остановка:

# Скачайте и установите Node.js с nodejs.org
# Затем установите Newman глобально
npm install -g newman

Проверка установки

Давайте убедимся, что всё работает правильно:

# Проверка версии Newman
newman --version
# Проверка версии Node.js
node --version

Если вы видите номера версий вместо сообщений об ошибках, поздравляю! Вы успешно присоединились к рядам энтузиастов автоматизированного тестирования.

Создание вашей первой коллекции тестирования API

Теперь начинается самое интересное — создание нашего первого автоматизированного набора тестов. Мы создадим подробный пример, используя типичный REST API с операциями CRUD.

Настройка структуры коллекции

Откройте Postman и создайте новую коллекцию под названием «API Automation Demo». Это будет наша площадка для тестирования, где мы реализуем все четыре операции CRUD:

  • POST — Создать пользователя;
  • GET — Получить данные пользователя;
  • PUT — Обновить информацию пользователя;
  • DELETE — Удалить пользователя.

Для каждого запроса мы добавим соответствующий URL, заголовки и, самое главное, подробные тестовые скрипты, которые проверяют, что наш API ведёт себя именно так, как ожидалось.

Написание надёжных тестовых скриптов

Здесь происходит волшебство. Postman использует JavaScript для тестовых скриптов, и поверьте мне, как только вы освоите это, вы удивитесь, как жили без автоматических утверждений:

// Базовая проверка кода состояния
pm.test("Статус-код равен 200", function () {
    pm.response.to.have.status(200);
});
// Проверка производительности времени отклика
pm.test("Время отклика приемлемое", function () {
    pm.expect(pm.response.responseTime).to.be.below(500);
});
// Проверка структуры JSON
pm.test("Отклик содержит данные пользователя", function () {
    const jsonData = pm.response.json();
    pm.expect(jsonData).to.have.property('id');
    pm.expect(jsonData).to.have.property('name');
    pm.expect(jsonData).to.have.property('email');
});
// Проверка типа данных
pm.test("ID пользователя — число", function () {
    const jsonData = pm.response.json();
    pm.expect(jsonData.id).to.be.a('number');
});

Переменные окружения и управление данными

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

// Динамическая установка переменных окружения
pm.test("Сохранить ID пользователя для последующих запросов", function () {
    const jsonData = pm.response.json();
    pm.environment.set("userId", jsonData.id);
});
// Использование переменных окружения в запросах
// URL: {{baseUrl}}/users/{{userId}}

Newman: ваша мощь тестирования в командной строке

После того как вы создали идеальную коллекцию в Postman, пришло время использовать возможности автоматизации Newman. Сначала экспортируйте свою коллекцию в формате JSON из Postman.

Базовое использование Newman

Самый простой способ запустить ваши тесты:

# Запуск коллекции
newman run API_Automation_Demo.postman_collection.json
# Запуск с переменными окружения
newman run API_Automation_Demo.postman_collection.json \
  -e Production.postman_environment.json

Расширенные опции Newman

Newman предлагает сокровищницу опций для опытных пользователей:

# Запуск с подробной отчётностью
newman run collection.json \
  --reporters cli,html \
  --reporter-html-export report.html
# Запуск с файлом данных для тестирования на основе данных
newman run collection.json \
  --data test-data.csv \
  --iteration-count 5
# Запуск с настраиваемым таймаутом и задержками
newman run collection.json \
  --timeout 30000 \
  --delay-request 100

Тестирование на основе данных: тестирование в больших масштабах

Одна из самых мощных функций Newman — возможность запускать один и тот же набор тестов с несколькими наборами данных. Это идеально подходит для тестирования различных сценариев без дублирования вашей логики тестирования.

Создайте CSV-файл с вашими тестовыми данными:

name,email,age
John Doe,[email protected],30
Jane Smith,[email protected],25
Bob Johnson,[email protected],35

Затем используйте его в вашей команде Newman:

newman run collection.json --data users.csv

В ваших запросах Postman ссылайтесь на данные, используя переменные {{name}}, {{email}} и {{age}}.

Интеграция с CI/CD: Святой Грааль автоматизации

Здесь всё становится действительно интересным. Интеграция Newman в ваш конвейер CI/CD означает, что ваши тесты API запускаются автоматически при каждом изменении кода, обнаруживая проблемы до того, как они дойдут до продакшена.

graph LR A[Commit кода] --> B[Запуск конвейера CI/CD] B --> C[Сборка приложения] C --> D[Развёртывание в тестовую среду] D --> E[Запуск тестов Newman] E --> F{Тесты пройдены?} F -->|Да| G[Развёртывание в продакшен] F -->|Нет| H[Оповестить команду и заблокировать развёртывание] H --> I[Исправить проблемы] I --> A

Интеграция с GitHub Actions

Вот практический рабочий процесс GitHub Actions, который запускает ваши тесты Newman:

name: Тесты API
on: [push, pull_request]
jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Установка Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '16'
      - name: Установка Newman
        run: npm install -g newman
      - name: Запуск тестов API
        run: |
          newman run tests/api-collection.json \
            --environment tests/test-environment.json \
            --reporters cli,junit \
            --reporter-junit-export results.xml          
      - name: Публикация результатов тестирования
        uses: dorny/test-reporter@v1
        if: always()
        with:
          name: Результаты тестирования API
          path: results.xml
          reporter: java-junit

Пример Jenkins Pipeline

Для энтузиастов Jenkins вот скрипт конвейера:

pipeline {
    agent any
    stages {
        stage('Установка зависимостей') {
            steps {
                sh 'npm install -g newman'
            }
        }
        stage('Запуск тестов API') {
            steps {
                sh '''
                    newman run api-tests.json \
                      --environment prod-env.json \
                      --reporters cli,html \
                      --reporter-html-export newman-report.html
                '''
            }
        }
    }
    post {
        always {
            publishHTML([
                allowMissing: false,
                alwaysLinkToLastBuild: true,
                keepAll: true,
                reportDir: