cy.request() для API-тестирования

cy.request() — это встроенная команда Cypress, предназначенная для выполнения HTTP-запросов без необходимости взаимодействия с пользовательским интерфейсом. Она идеально подходит для тестирования RESTful API, проверки ответов сервера, работы с токенами аутентификации и подготовки данных для UI-тестов.


Основы cy.request()

Команда cy.request() может принимать как строку URL, так и объект с настройками запроса:

// Простейший GET-запрос
cy.request('https://jsonplaceholder.typicode.com/posts/1')
  .then((response) => {
    expect(response.status).to.eq(200);
    expect(response.body).to.have.property('id', 1);
  });

Ключевые свойства объекта запроса:

  • method — метод HTTP-запроса (GET, POST, PUT, DELETE и др.).
  • url — адрес ресурса.
  • body — тело запроса (для POST, PUT, PATCH).
  • headers — заголовки HTTP.
  • qs — параметры строки запроса.
  • failOnStatusCode — отключает автоматическую проверку кода ответа.

Пример с объектом запроса:

cy.request({
  method: 'POST',
  url: '/api/users',
  body: { name: 'John', job: 'Developer' },
  headers: { 'Content-Type': 'application/json' },
}).then((response) => {
  expect(response.status).to.eq(201);
  expect(response.body).to.have.property('name', 'John');
});

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

Статус-код HTTP является одним из ключевых показателей успешности запроса:

cy.request('/api/posts')
  .its('status')
  .should('eq', 200);

Для проверки структуры и содержания ответа удобно использовать chai assertions:

cy.request('/api/users')
  .then((response) => {
    expect(response.body).to.be.an('object');
    expect(response.body.data).to.be.an('array');
    expect(response.body.data[0]).to.have.all.keys('id', 'email', 'first_name', 'last_name', 'avatar');
  });

Отправка запросов с аутентификацией

Cypress поддерживает различные способы передачи токенов и данных авторизации. Наиболее часто используется Bearer Token:

cy.request({
  method: 'GET',
  url: '/api/protected',
  headers: {
    Authorization: `Bearer ${Cypress.env('API_TOKEN')}`
  }
}).then((response) => {
  expect(response.status).to.eq(200);
});

Можно также использовать Basic Auth:

cy.request({
  method: 'GET',
  url: '/api/private',
  auth: { username: 'admin', password: 'password123' },
}).its('status').should('eq', 200);

Использование параметров запроса

Для GET-запросов с параметрами удобно использовать ключ qs:

cy.request({
  method: 'GET',
  url: '/api/users',
  qs: { page: 2, limit: 10 }
}).then((response) => {
  expect(response.status).to.eq(200);
  expect(response.body.page).to.eq(2);
});

qs автоматически сериализует объект в query string, что упрощает работу с динамическими параметрами.


Работа с ошибками и нестандартными статусами

По умолчанию Cypress выбрасывает исключение при кодах ответа, отличных от 2xx. Чтобы проверить ошибки сервера, необходимо установить failOnStatusCode: false:

cy.request({
  method: 'GET',
  url: '/api/invalid-endpoint',
  failOnStatusCode: false
}).then((response) => {
  expect(response.status).to.eq(404);
});

Интеграция cy.request() в UI-тесты

API-запросы можно использовать для подготовки данных перед запуском тестов интерфейса:

beforeEach(() => {
  cy.request('POST', '/api/users', { name: 'Test User', job: 'QA' });
});

it('Проверка добавленного пользователя на UI', () => {
  cy.visit('/users');
  cy.contains('Test User').should('exist');
});

Такой подход ускоряет тесты, исключая необходимость ручного создания данных через UI.


Асинхронность и цепочки команд

cy.request() возвращает объект Chainable, что позволяет строить цепочки проверок и использовать данные ответа в последующих шагах:

cy.request('/api/users/1')
  .then((response) => {
    const userId = response.body.id;
    return cy.request(`/api/posts?userId=${userId}`);
  })
  .its('body')
  .should('have.length.greaterThan', 0);

Логирование и отладка

Для отладки можно использовать встроенный cy.log или console.log:

cy.request('/api/users')
  .then((response) => {
    cy.log('Количество пользователей: ' + response.body.data.length);
    console.table(response.body.data);
  });

Советы по использованию cy.request()

  • Всегда проверять статус-код и структуру ответа, чтобы тесты были стабильными.
  • Использовать environment variables для токенов и URL, чтобы не хранить их в коде.
  • Для сложных сценариев сочетать cy.request() с UI-тестами, чтобы ускорять подготовку данных.
  • Отключать failOnStatusCode при тестировании негативных сценариев.
  • Строить цепочки запросов через then, чтобы избежать проблем с асинхронностью.

cy.request() является мощным инструментом для API-тестирования, позволяющим создавать надежные и быстрые тесты, интегрируя их с интерфейсными проверками и обеспечивая детальный контроль над HTTP-запросами.