API-тестирование — это та часть QA, которую часто делают на глаз. Открыл Postman, потыкал пару эндпоинтов, всё ответило 200 — окей, работает. Но это не тестирование, это проверка что сервер вообще живой.

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


Что вообще нужно проверять в API

Разобьём на категории — так проще не пропустить ничего важного.

1. Статус-коды

Самое очевидное, но часто делают неправильно. Мало проверить что пришёл 200. Нужно проверять что приходит правильный код в правильной ситуации:

Ситуация

Ожидаемый код

Успешное создание ресурса

201, не 200

Ресурс не найден

404

Нет прав доступа

403

Не авторизован

401

Невалидные данные

400 или 422

Ошибка на сервере

500

Типичная ошибка — когда бэкенд возвращает 200 с телом {"error": "not found"}. Это неправильно, и это нужно ловить.

2. Структура ответа

Проверяйте не только что данные пришли, но что они пришли в правильной форме:

  • Все обязательные поля присутствуют

  • Типы данных совпадают со схемой (строка не пришла вместо числа)

  • Вложенные объекты не null там, где не должны быть

  • Массивы не возвращают объект и наоборот

3. Граничные значения

Это то, где чаще всего прячутся баги:

  • Пустое тело запроса

  • Обязательное поле отсутствует

  • Поле есть, но пустая строка

  • Числовое поле — отрицательное значение, ноль, очень большое число

  • Строковое поле — 1 символ, максимально длинная строка, спецсимволы, SQL-инъекция, XSS

4. Аутентификация и авторизация

  • Запрос без токена → 401

  • Запрос с протухшим токеном → 401

  • Запрос с токеном другого пользователя к чужим данным → 403

  • Пользователь с правами read пытается сделать write → 403

5. Заголовки

  • Content-Type в ответе соответствует тому, что вернули

  • CORS-заголовки если нужны

  • Rate limiting заголовки если есть


Как это делать в Postman

Postman позволяет писать тесты прямо внутри коллекции. Вкладка Tests в каждом запросе — это JavaScript, который запускается после получения ответа.

Базовые проверки

// Проверка статус-кода
pm.test("Статус 200", () => {
    pm.response.to.have.status(200);
});

// Проверка времени ответа
pm.test("Ответ быстрее 500мс", () => {
    pm.expect(pm.response.responseTime).to.be.below(500);
});

// Проверка Content-Type
pm.test("Возвращает JSON", () => {
    pm.response.to.have.header("Content-Type", "application/json; charset=utf-8");
});

Проверка структуры ответа

const response = pm.response.json();

pm.test("Есть поле id", () => {
    pm.expect(response).to.have.property("id");
});

pm.test("id это число", () => {
    pm.expect(response.id).to.be.a("number");
});

pm.test("Есть поле email и оно не пустое", () => {
    pm.expect(response.email).to.be.a("string").and.not.empty;
});

Проверка авторизации — негативный сценарий

Создайте отдельный запрос без заголовка Authorization и добавьте тест:

pm.test("Без токена — 401", () => {
    pm.response.to.have.status(401);
});

pm.test("Тело содержит сообщение об ошибке", () => {
    const response = pm.response.json();
    pm.expect(response).to.have.property("message");
});

Переменные окружения

Один из самых полезных паттернов — сохранять данные из ответа в переменные и использовать в следующих запросах. Например, логин → сохранить токен → использовать в остальных запросах:

// В тесте запроса POST /auth/login
const response = pm.response.json();
pm.environment.set("auth_token", response.token);

Дальше в заголовках остальных запросов просто пишете {{auth_token}}.


Автотесты на JavaScript (Jest + axios)

Postman удобен для ручного исследования и быстрых проверок. Но если хотите тесты в CI/CD — лучше написать их кодом.

Простой пример с Jest и axios:

// user.test.js
const axios = require("axios");

const BASE_URL = "https://api.example.com";
const TOKEN = process.env.API_TOKEN;

const client = axios.create({
    baseURL: BASE_URL,
    headers: { Authorization: `Bearer ${TOKEN}` }
});

describe("GET /users/:id", () => {

    test("Возвращает пользователя по id", async () => {
        const response = await client.get("/users/1");

        expect(response.status).toBe(200);
        expect(response.data).toMatchObject({
            id: expect.any(Number),
            email: expect.any(String),
            name: expect.any(String),
        });
    });

    test("Возвращает 404 для несуществующего id", async () => {
        await expect(
            client.get("/users/999999")
        ).rejects.toMatchObject({
            response: { status: 404 }
        });
    });

    test("Возвращает 401 без токена", async () => {
        await expect(
            axios.get(`${BASE_URL}/users/1`)
        ).rejects.toMatchObject({
            response: { status: 401 }
        });
    });

});

Запуск:

npm install jest axios
npx jest user.test.js

Чеклист для API-тестирования

Можно использовать как шаблон для каждого нового эндпоинта:

Позитивные сценарии

  • [ ] Запрос с валидными данными возвращает правильный статус-код

  • [ ] Структура ответа соответствует документации

  • [ ] Все обязательные поля присутствуют

  • [ ] Типы данных корректны

  • [ ] Время ответа в норме

Негативные сценарии

  • [ ] Запрос без авторизации → 401

  • [ ] Запрос с чужим токеном → 403

  • [ ] Отсутствует обязательное поле → 400/422

  • [ ] Неверный тип данных в поле → 400/422

  • [ ] Несуществующий ресурс → 404

  • [ ] Пустое тело запроса → ожидаемая ошибка

Граничные значения

  • [ ] Минимальное допустимое значение

  • [ ] Максимальное допустимое значение

  • [ ] Ноль и отрицательные числа (если применимо)

  • [ ] Пустая строка

  • [ ] Спецсимволы и Unicode

  • [ ] Очень длинная строка

Безопасность

  • [ ] SQL-инъекция в строковых полях

  • [ ] XSS в строковых полях

  • [ ] Перебор чужих id (IDOR)


Варианты автоматизации с ИИ

ИИ в API-тестировании — это не замена ручным проверкам, а способ убрать рутину и найти то, до чего руки не доходят.

Генерация тест-кейсов по документации

Если у вас есть OpenAPI/Swagger-спецификация — можно скормить её в Claude или GPT и попросить сгенерировать тест-кейсы для каждого эндпоинта. Получите покрытие позитивных и негативных сценариев за несколько минут вместо часа ручной работы.

Пример промта:

Вот OpenAPI-спецификация для эндпоинта POST /users:
[вставить схему]

Сгенерируй тест-кейсы: позитивные сценарии, негативные, граничные значения.
Формат: Jest + axios. Используй реалистичные тестовые данные.

Автоматический анализ ответов

Если API возвращает текст или сложные структуры которые сложно проверить жёстким assertEqual — можно использовать LLM как валидатор. Например, проверить что ответ релевантен запросу, что тональность нейтральная, что нет лишних данных в ответе.

async function validateWithAI(prompt, response) {
    const result = await fetch("https://api.anthropic.com/v1/messages", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
            model: "claude-sonnet-4-20250514",
            max_tokens: 100,
            messages: [{
                role: "user",
                content: `Запрос: "${prompt}"\nОтвет API: "${response}"\n\nОтвет релевантен запросу? Ответь только: YES или NO`
            }]
        })
    });
    const data = await result.json();
    return data.content[0].text.trim() === "YES";
}

Генерация граничных значений

Попросите ИИ придумать нестандартные входные данные для конкретного поля. Особенно полезно для строковых полей — модель придумает комбинации, до которых вы сами можете не додуматься: смешанные алфавиты, RTL-текст, эмодзи, невидимые символы, очень специфичные паттерны.

Что ИИ не заменит

Понимание бизнес-логики. ИИ не знает, почему у вас поле discount не может быть больше 100 если пользователь не премиум. Это контекст, который живёт в голове у команды. Тест-кейсы на бизнес-правила всё равно придётся писать руками.

Если есть вопросы или хотите разобрать конкретный кейс — пишите в комментарии.


💼 Занимаюсь QA и AI-интеграциями на фрилансе. Kwork