Тестирование API: как проверять REST‑ендпоинты на Python и JavaScript
Зачем проверять API перед интеграцией
API — это контракт между вашим приложением и внешним сервисом. Неправильно реализованный или плохо документированный API приводит к багам, уязвимостям и простоям. Простая проверка ответа эндпоинта помогает понять, можно ли на него опираться в продакшне.
Кратко, тестирование API отвечает на вопросы:
- Возвращает ли API ожидаемые статус‑коды (200/201/400/401/403/404/500 и т. д.)?
- Возвращаются ли данные в ожидаемом формате (JSON/XML/multipart/HTML)?
- Принимает ли API корректно сформированные тела запросов и учитывает ли валидацию?
- Корректно ли обрабатывается авторизация и заголовки?
- Как ведёт себя API при повышенной нагрузке?
Что такое тестирование API
Тестирование API — это набор техник и проверок, направленных на оценку того, насколько API пригоден для использования вашим приложением. Включает функциональное тестирование (валидация ответов), тестирование безопасности (авторизация, доступ), тестирование производительности и устойчивости.
Определим пару терминов в одну строку:
- Эндпоинт — URL, к которому вы делаете запрос (например, /products или /users/123).
- Payload — тело запроса (JSON, form-data и т. п.).
Обзор подхода в статье
Мы фокусируемся на валидации ответов CRUD‑эндпоинтов (Get, Post, Put, Delete) с практическими примерами. В качестве целевой системы используем публичное учебное API: https://fakestoreapi.com/products. Примеры демонстрируют, как:
- Проверить статус ответа
- Получить и распарсить JSON
- Вытащить нужные поля (например, price)
- Создать/обновить/удалить ресурс

Как тестировать GET‑эндпоинт на JavaScript
В браузере и в Node.js удобно использовать fetch или Axios. Ниже — минимальный пример на fetch для проверки статуса и получения JSON:
fetch('https://fakestoreapi.com/products',
).then(res =>{
console.log(res)
})
Если ответ валиден, вы увидите объект ответа с полем status обычно 200. Далее можно получить тело и работать с данными:
fetch('https://fakestoreapi.com/products',
).then(res =>{
if (res.ok){
return res.json()
}
}).then(response=>{
console.log(response)
}).catch(err => console.log(err))
Ответ API (пример формата JSON) можно увидеть на скриншоте:

Чтобы выбрать только цены всех товаров, используйте map:
fetch('https://fakestoreapi.com/products',
).then(res =>{
if (res.ok){
return res.json()
}
}).then(response=>{
response.map(data =>{
console.log(data.price)
})
// console.log(response)
}).catch(err => console.log(err))
Результат примера логирования цен показан ниже:

Как тестировать GET‑эндпоинт на Python
В Python стандартный инструмент для простых HTTP‑запросов — библиотека requests.
import requests
data = requests.get('https://fakestoreapi.com/products')
print(data.status_code)
Чтобы получить сам JSON:
import requests
data = requests.get('https://fakestoreapi.com/products')
myData = data.json()
print(myData)
Пример результата показан на скриншоте:

Для извлечения цен:
import requests
data = requests.get('https://fakestoreapi.com/products')
myData = data.json()
indexes = 0
for i in myData:
goods = myData[indexes]
indexes +=1
print(goods["price"])
Результат выполнения (список цен) — демонстрация ниже:

Тестирование POST на JavaScript
POST‑запросы содержат тело. Укажите метод и заголовки, затем сериализуйте payload в JSON:
// Specify the payload
let payload = {
title: 'new product',
price: 13.5,
description: 'test description',
image: '',
category: 'electronic'
}
fetch('https://fakestoreapi.com/products',
{
method: "Post",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify(payload) //convert the payload to JSON
}
).then(res =>{
if (res.ok){
console.log(res.status)
return res.json()
}
}).then(response => {
console.log(response)
}).catch(err => console.log(err))
HTTP‑код 200 или 201 обычно означает успешное создание/обновление. Лог ответа содержит возвращённый объект.
Тестирование POST на Python
Аналогично, в requests используйте requests.post:
import requests
payload = {
'title': 'new product',
'price': 13.5,
'description': 'test description',
'image': '',
'category': 'electronic'
}
Posted = requests.post('https://fakestoreapi.com/products',
data = payload
)
print(Posted.status_code)
print(Posted.json())
Обратите внимание: некоторые API ожидают JSON в теле (используйте json=payload в requests), другие — form data (data=payload). Проверяйте документацию.
Тестирование PUT (обновление) и DELETE
Обновление с использованием PUT похоже на POST, только указывайте метод PUT и, как правило, включайте идентификатор ресурса:
// Specify the payload
let payload = {
title: 'new product',
price: 13.5,
description: 'test description',
image: '',
category: 'electronic'
}
fetch('https://fakestoreapi.com/products/19',
{
method: "Put",
headers:{
'Content-Type': 'application/json'
},
body: JSON.stringify(payload) //convert the payload into JSON
}
).then(res =>{
if (res.ok){
console.log(res.status)
return res.json()
}
}).then(response => {
console.log(response)
}).catch(err => console.log(err))
И пример на Python:
import requests
payload = {
'title': 'new product',
'price': 13.5,
'description': 'test description',
'image': '',
'category': 'electronic'
}
Posted = requests.put('https://fakestoreapi.com/products/19',
data = payload
)
print(Posted.status_code)
print(Posted.json())
Удаление — простой DELETE без тела:
fetch('https://fakestoreapi.com/products/19',
{
method: "Delete",
headers:{
'Content-Type': 'application/json'
}
}
).then(res =>{
if (res.ok){
console.log(res.status)
return res.json()
}
}).then(response => {
console.log(response)
}).catch(err => console.log(err))
И на Python:
import requests
Posted = requests.delete('https://fakestoreapi.com/products/19',
)
print(Posted.status_code)
print(Posted.json())Обе версии возвращают код операции и, при необходимости, удалённый объект.
Универсальность методов
Методы тестирования CRUD, показанные выше, применимы к большинству REST‑API. Различия обычно только в:
- Формате тела (json vs form-data)
- Требованиях к заголовкам (Authorization, Accept, Custom‑Headers)
- Параметрах в пути и query‑параметрах
Перед тестом внимательно изучите документацию API: какие методы разрешены, как форматируются ответы и какие значения обязательны.
Практические советы по работе с реальными API
- Всегда проверяйте код ответа и структуру тела (schema). Никогда не полагайтесь только на код ответа.
- Логируйте полные ответы в тестовой среде для отладки.
- Для запросов с авторизацией храните токены в переменных окружения, а не в коде.
- Тестируйте негативные случаи (невалидные данные, отсутствие обязательных полей, неправильный токен).
Быстрый чек‑лист перед интеграцией (роль: разработчик/QA)
- Протестирован GET базового ресурса — код 200, структура JSON валидна
- Проверены поля на предмет типизации и обязательности
- POST возвращает 201/200 и создаёт ресурс с ожидаемыми полями
- PUT/PATCH обновляет целевой ресурс по ID
- DELETE удаляет ресурс и возвращает корректный статус
- Обработаны ошибки 400/401/403/404/500
- Протестирована авторизация и ротация токенов
- Есть тестовые сценарии для пиковых нагрузок (smoke/load)
Критерии приёмки
- Все CRUD‑эндпоинты успешно проходят автоматизированные тесты.
- JSON‑схемы совпадают с документацией.
- На негативных сценариях возвращаются предсказуемые и документированные ошибки.
- Наличие переключателя окружений (staging/prod) и безопасного хранения секретов.
Когда показанный подход не работает
- SOAP и RPC‑ориентированные сервисы не используют стандартные REST‑паттерны: для них нужны SOAP клиенты или специальные библиотеки.
- Слоистые API с сильной бизнес‑логикой могут требовать эмуляции внешних событий, которые нельзя имитировать простыми HTTP‑запросами.
- API с asynchrony (webhooks, long polling, server‑sent events) потребуют подходов, отличных от синхронных fetch/requests.
Альтернативные инструменты и подходы
- Postman / Insomnia — удобный GUI для ручного тестирования, генерации коллекций и экспортов.
- Newman — запуск коллекций Postman в CI.
- Karate, RestAssured — тестовые фреймворки для автоматизации на Java/Kotlin.
- Pytest + requests — удобная связка для автоматизированных тестов на Python с фикстурами.
- Pact — контрактное тестирование (consumer/provider) для предотвращения разрывов контрактов.
Мини‑плейбук: проверка API за 15 минут
- Выполните GET корневого ресурса, проверьте код 200 и структуру.
- Выполните POST с тестовым payload, проверьте код 200/201 и сохранённые поля.
- Выполните PUT/PATCH на созданном ресурсе, проверьте изменения.
- Выполните DELETE и убедитесь, что GET по удалённому ID возвращает 404.
- Проверка авторизации: повторите запрос без токена — ожидайте 401/403.
- Сохраните все запросы в коллекцию Postman/Newman для CI.
Примеры: заголовок Authorization и JSON‑тело
JavaScript, добавление Bearer‑токена:
fetch('https://example.com/api/secure', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_TOKEN_HERE',
'Accept': 'application/json'
}
})
.then(r => r.json())
.then(console.log)Python, передача токена:
import requests
headers = {'Authorization': 'Bearer ' + token, 'Accept': 'application/json'}
r = requests.get('https://example.com/api/secure', headers=headers)
print(r.status_code, r.json())Наборы тест‑кейсов и критерии приёмки
- Позитивный GET: код 200, тело — массив/объект, поля присутствуют.
- Негативный GET (неверный ID): код 404.
- Позитивный POST: код 201/200, возвращается созданный объект с id.
- Негативный POST (отсутствуют обязательные поля): код 400 и сообщение об ошибке.
- Авторизация: запрос без токена — код 401.
- Консистентность: повторный GET после POST возвращает созданный ресурс.
Критерий приёмки: все тест‑кейсы проходят без ошибок в тестовой среде, а автоматизация интегрирована в CI (run on push/PR).
Безопасность и конфиденциальность
- Никогда не храните реальные секреты в репозитории. Используйте secret‑store CI/CD.
- Тесты не должны очищать данные продакшена — используйте тестовые среды.
- Проверяйте заголовки CORS и политики доступа при интеграции фронтенда.
Модель мышления при тестировании API (эвристики)
- Начни с контрактов: документация + OpenAPI/Swagger.
- Делай «самые простые» запросы сначала (smoke-tests), затем негативные и граничные.
- Автоматизируй критичные пути и интегрируй в CI.
- Не доверяй ответам: валидируй структуру и значения.
Частые ошибки и как их избежать
- Привязывание тестов к нестабильным данным — используйте фикстуры/изолированные тестовые базы.
- Игнорирование ошибок сети — добавьте повторные попытки (retries) и таймауты.
- Отсутствие проверки схемы — используйте JSON Schema или OpenAPI валидаторы.
FAQ
Нужно ли всегда проверять все эндпоинты перед релизом?
Да, особенно критичные для бизнеса. Минимальный набор — smoke‑тесты основных путей и проверки авторизации.
Можно ли прогонять тесты против продакшна?
В исключительных случаях можно выполнять readonly проверки, но создание/удаление данных в продакшне следует избегать.
Чем лучше автоматизировать тесты: Postman или код?
Для быстрых ручных проверок удобен Postman. Для повторяемых CI‑прогонов предпочтителен код (pytest, Jest, Karate и т. п.).
Итог
Тестирование API — обязательный шаг перед глубоким использованием внешних сервисов. Простые проверки CRUD, валидация статусов и структуры ответа помогут решить большинство проблем на ранних этапах. Интегрируйте автоматические проверки в CI, храните секреты безопасно и покрывайте как позитивные, так и негативные сценарии.