Работа с API в интеграционных тестах
Веб-приложения редко бывают изолированными, поэтому API-запросы — краеугольный камень большинства приложений. Cypress позволяет легко тестировать эти запросы с использованием встроенных методов. Представьте себе этот процесс как проверку вроде: "Алло, сервер, ты меня слышишь?".
Cypress предоставляет метод cy.request для выполнения HTTP-запросов. Он поддерживает все стандартные методы, такие как GET, POST, PUT, DELETE. Вот простой пример, чтобы проверить API-запрос:
describe('API Тесты', () => {
it('Должен получить список пользователей', () => {
cy.request('GET', 'https://jsonplaceholder.typicode.com/users').then((response) => {
// Проверяем статус ответа
expect(response.status).to.eq(200);
// Проверяем, что получили массив с данными
expect(response.body).to.be.an('array');
// Убедимся, что в массиве есть хотя бы один пользователь
expect(response.body.length).to.be.greaterThan(0);
});
});
});
Здесь мы отправляем GET-запрос на API, проверяем статус ответа, его тело (массив) и наличие данных. Это напоминает "заход в гости к серверу на чай, чтобы узнать, все ли в порядке".
Обработка ответов API и проверка данных
После того как запрос выполнен, результат нужно проанализировать. Cypress позволяет проверять как мета-информацию (например, статус-код), так и содержимое тела ответа. Здесь важно помнить, что Cypress автоматически обрабатывает JSON и превращает его в объект.
Представим, что у нас есть API для получения информации о пользователях, и нам нужно проверить структуру возвращаемых данных. Для этого удобно использовать интерфейсы TypeScript.
interface User {
id: number;
name: string;
username: string;
email: string;
}
describe('Проверка структуры данных', () => {
it('Должен вернуть корректную структуру данных', () => {
cy.request<[]>('GET', 'https://jsonplaceholder.typicode.com/users').then((response) => {
expect(response.status).to.eq(200);
// Проверяем, что каждый элемент соответствует интерфейсу User
response.body.forEach((user) => {
expect(user).to.have.all.keys('id', 'name', 'username', 'email');
});
});
});
});
Обратите внимание на передачу типа <User[]> в cy.request. Это позволяет нам работать с типизированными данными и избегать сюрпризов.
Тестирование обработки ошибок API
Ошибки при взаимодействии с API могут быть как реально ошибками сервера, так и результатом некорректных данных. Cypress позволяет легко тестировать как успешные, так и ошибочные запросы.
Допустим, у нас есть API с маршрутом для получения данных пользователя, но мы передаем несуществующий ID. Как приложение должно обработать эту ошибку? Давайте проверим:
describe('Тестирование ошибок API', () => {
it('Должен вернуть 404 для несуществующего пользователя', () => {
cy.request({
method: 'GET',
url: 'https://jsonplaceholder.typicode.com/users/999', // Несуществующий ID
failOnStatusCode: false, // Отключаем автоматическое завершение теста на ошибке
}).then((response) => {
// Проверяем статус ошибки
expect(response.status).to.eq(404);
// Проверяем, что тело ответа пустое
expect(response.body).to.be.empty;
});
});
});
failOnStatusCode: false — это флаг, который позволяет тесту продолжать выполнение даже при ошибочном статусе (например, 404 или 500).
Реальные кейсы: тестирование взаимодействия API и UI
Теперь давайте посмотрим на сценарий, где наш фронтенд работает с API. Мы не только проверим запрос, но и убедимся, что данные отображаются корректно в пользовательском интерфейсе.
Вот пример: у нас есть список пользователей, загружаемый через API. Наша цель — убедиться, что данные отображаются на странице после успешного запроса.
describe('Проверка отображения данных на UI', () => {
beforeEach(() => {
cy.visit('/users'); // Переходим на страницу списка пользователей
});
it('Должен отобразить пользователей из API', () => {
cy.intercept('GET', '/users', { fixture: 'users.json' }).as('getUsers'); // Перехватываем запрос и возвращаем фикстуру
cy.wait('@getUsers'); // Ждем выполнения запроса
// Проверяем, что элементы отображаются
cy.get('.user-item').should('have.length', 10); // Фикстура содержит 10 пользователей
cy.get('.user-item').first().should('contain.text', 'Leanne Graham'); // Проверяем первый элемент
});
});
Здесь мы используем cy.intercept для симуляции запроса и подмены ответа с помощью фиксированного файла users.json. Это помогает изолировать тест и избежать зависимостей от реального сервера.
Использование Cypress для тестирования POST и DELETE
Кроме чтения данных, приложения также часто отправляют запросы для создания или удаления информации. Проверим корректность отправки таких запросов.
Пример: проверка создания нового пользователя
describe('Проверка POST-запросов', () => {
it('Должен создать нового пользователя', () => {
cy.request('POST', 'https://jsonplaceholder.typicode.com/users', {
name: 'John Doe',
username: 'johndoe',
email: 'john.doe@example.com',
}).then((response) => {
// Проверяем статус успешного создания
expect(response.status).to.eq(201);
// Проверяем, что данные сохранены корректно
expect(response.body).to.include({
name: 'John Doe',
username: 'johndoe',
email: 'john.doe@example.com',
});
});
});
});
Пример: удаление пользователя
describe('Проверка DELETE-запросов', () => {
it('Должен удалить пользователя', () => {
cy.request('DELETE', 'https://jsonplaceholder.typicode.com/users/1').then((response) => {
expect(response.status).to.eq(200); // Успешное удаление
});
});
});
Какие ошибки можно заметить?
Тестирование API — это возможность не только убедиться в корректности работы приложения, но и найти проблемы в самом API. Например, можно заметить:
- Непоследовательные ответы, где структура данных меняется.
- Ошибки обработки неподдерживаемых запросов (например, DELETE для ресурса, который нельзя удалить).
- Проблемы с производительностью, если запросы выполняются слишком долго.
В реальной жизни такие тесты могут быть полезны и для DevOps-инженеров, которые настраивают сервер, и для бекендеров, которые оптимизируют API.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ