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
