Тестирование API: Unit, интеграционные и контрактные тесты
Надёжные API требуют продуманной стратегии тестирования, которая сочетает unit-тесты, интеграционные тесты и контрактные тесты. Это позволяет выявлять ошибки на ранних этапах и защищать контракты между сервисом и клиентами.
Краткое описание
Тестирование API охватывает все проверки, которые гарантируют корректность, безопасность, производительность и стабильность интерфейса. Unit-тесты проверяют изолированные функции, контроллеры или обработчики без внешних зависимостей. Интеграционные тесты проверяют взаимодействие нескольких компонентов: API, базы данных, внешних сервисов. Контрактные тесты гарантируют, что поставщик и потребитель API соблюдают одинаковый контракт, например через OpenAPI или Pact. Хорошая стратегия покрывает API на разных уровнях, полностью автоматизирована и работает в конвейере Continuous Integration. Цель состоит в раннем обнаружении ошибок, предотвращении регрессий и надёжной документации контракта между API и клиентами.
Основные компоненты
Unit-тесты для API
Unit-тесты проверяют небольшие изолированные единицы API: обработчики, контроллеры, логику валидации или маппинга. Внешние зависимости, такие как базы данных или HTTP-клиенты, заменяются на mock-объекты или заглушки. Unit-тесты работают быстро и дают оперативную обратную связь при изменениях кода.
Интеграционные тесты
Интеграционные тесты проверяют взаимодействие API с реальными или контейнеризованными зависимостями. Сюда входят обращения к базе данных, очереди сообщений, внешние API и сервисы аутентификации. Testcontainers позволяют запускать базы данных и другие сервисы в тестовой среде.
End-to-End тесты
End-to-End тесты имитируют работу API со стороны клиента. Они отправляют реальные HTTP-запросы и проверяют полный ответ. Часто используются инструменты как Postman, REST Assured или Supertest. E2E тесты работают медленнее, но охватывают весь стек приложения.
Контрактные тесты
Контрактные тесты проверяют, соблюдают ли API и клиент оговорённый контракт. Контракт может быть определён через OpenAPI, JSON Schema или фреймворки вроде Pact. Consumer Driven Contracts позволяют клиентам сообщать свои ожидания от поставщика.
Consumer Driven Contracts
При использовании Consumer Driven Contracts клиенты описывают свои ожидания как контракт. Поставщик должен выполнить этот контракт. Pact является популярным фреймворком для этого подхода. Он предотвращает непредвиденное нарушение клиентов при изменениях API.
Тестовая пирамида
Тестовая пирамида говорит: нужно иметь много быстрых unit-тестов, меньше интеграционных тестов и лишь несколько медленных E2E тестов. Контрактные тесты дополняют пирамиду между интеграционным и unit-уровнем. Они помогают эффективно проверять контракты интерфейсов.
Тестовые данные и fixtures
Тестовые данные должны быть воспроизводимыми и изолированными. Fixtures, фабрики или методы инициализации создают необходимые данные перед каждым тестом. Тесты с базой данных должны использовать транзакции или свежие копии БД, чтобы состояния между тестами не пересекались.
Mocking и Stubbing
Mocking заменяет внешние зависимости контролируемыми объектами. Stubbing предоставляет заранее определённые ответы. Обе техники важны для unit-тестов, но не нужны для интеграционных тестов, где используются реальные зависимости.
Fuzzing и negative-тесты
Negative-тесты проверяют, как API обрабатывает некорректные входные данные, пропущенные поля или неожиданные типы данных. Fuzzing автоматически генерирует множество случайных или полусхематичных входных данных для поиска уязвимостей.
Performance-тесты
Performance-тесты проверяют время ответа, пропускную способность и поведение под нагрузкой. Используются инструменты вроде k6, JMeter или Gatling. Они дополняют функциональные тесты и важны для API с высокими требованиями к доступности и масштабируемости.
Интеграция с CI/CD
API-тесты должны автоматически запускаться в конвейере Continuous Integration. Unit-тесты запускаются при каждой сборке, интеграционные тесты перед слиянием, контрактные тесты при изменениях API, E2E тесты перед развёртыванием. Ошибки останавливают сборку на раннем этапе.
Практический пример
Команда на Node.js тестирует API заказов на всех уровнях.
Unit-тест валидации заказа:
describe('Order validation', () => {
test('rejects negative quantity', () => {
const result = validateOrder({ customerId: 1, items: [{ productId: 5, quantity: -1 }] });
expect(result.valid).toBe(false);
expect(result.errors).toContain('quantity must be positive');
});
});
Интеграционный тест с Testcontainers:
describe('POST /orders', () => {
test('creates an order and persists it', async () => {
const response = await request(app)
.post('/orders')
.send({ customerId: 1, items: [{ productId: 5, quantity: 2 }] })
.expect(201);
expect(response.body.id).toBeDefined();
expect(response.body.status).toBe('created');
const order = await db.query('SELECT * FROM orders WHERE id = ?', [response.body.id]);
expect(order).toHaveLength(1);
});
});
Контрактный тест с Pact:
const pact = new Pact({
consumer: 'web-shop',
provider: 'order-service',
});
await pact.addInteraction({
state: 'order can be created',
uponReceiving: 'a request to create an order',
withRequest: {
method: 'POST',
path: '/orders',
body: { customerId: 1, items: [{ productId: 5, quantity: 2 }] }
},
willRespondWith: {
status: 201,
body: { id: 1, status: 'created' }
}
});
Сочетание трёх уровней обеспечивает полную и своевременную проверку API.
FAQ: тестирование API
1. Что такое тестирование API?
2. Что такое unit-тест для API?
3. Что такое интеграционный тест?
4. Что такое контрактный тест?
5. Что такое Consumer Driven Contract Testing?
6. Что такое Pact?
7. Что такое тестовая пирамида?
8. Что такое mocking?
9. Что такое Testcontainers?
10. Что такое end-to-end тест?
11. Что такое negative-тесты?
12. Что такое fuzzing?
13. Что такое performance-тесты для API?
14. Почему API-тесты должны запускаться в CI/CD?
15. Какие best practices для тестирования API?
Продолжаем обучение API
Следующий материал в нашем цикле посвящен реализации API Rate Limiting — разберемся, как внедрить Rate Limiting с использованием Token Bucket, Sliding Window и Redis.
Источники
- https://martinfowler.com/articles/consumerDrivenContracts.html
- https://docs.pact.io/
- https://www.testcontainers.org/
Рекомендуемые книги по тестированию и дизайну API
Если ты хочешь глубже погрузиться в API Testing, автоматизацию тестов и качество ПО, вот подборка полезных книг:
Keine Bücher für Kategorie "api-development" gefunden.



