Cypress API Testing Basics

Cypress can test backend APIs directly, without loading a full web page. This approach checks whether a server responds correctly to requests. This topic introduces the basics of API testing using Cypress.

The cy.request Command

The cy.request command sends an HTTP request directly to a server address.

cy.request('GET', '/api/products').then((response) => {
  expect(response.status).to.equal(200)
})

This test sends a request to the products endpoint and checks that the server responded with a success status code.

A Simple Way to Picture It

Think of an API request as ordering food over the phone instead of visiting the restaurant in person. You do not see the dining room or the menu display, but you still receive the food and can check if the order matches what you asked for. API testing checks the server's response the same way, without loading the visual page.

Checking Response Data

A response object includes the status code, headers, and body returned by the server.

cy.request('GET', '/api/products').then((response) => {
  expect(response.status).to.equal(200)
  expect(response.body).to.have.length.greaterThan(0)
  expect(response.body[0]).to.have.property('name')
})

This example confirms the server returned at least one product with a name property included.

API Request Flow Diagram

Test sends request (cy.request)
      |
      v
Server processes the request
      |
      v
Server sends back status, headers, and body
      |
      v
Test checks the response with assertions

Sending Data with a POST Request

API tests often need to create data using a POST request, sending information inside the request body.

cy.request('POST', '/api/products', {
  name: 'Wireless Mouse',
  price: 25
}).then((response) => {
  expect(response.status).to.equal(201)
})

A status code of 201 typically confirms the server successfully created a new resource.

Testing Authentication Headers

Some API endpoints require an authentication token included in the request headers.

cy.request({
  method: 'GET',
  url: '/api/orders',
  headers: {
    Authorization: 'Bearer sample-token-123'
  }
}).then((response) => {
  expect(response.status).to.equal(200)
})

Why API Testing Runs Faster

API tests skip rendering a full page, avoiding the time needed to load images, styles, and scripts. This speed makes API tests useful for checking backend logic quickly, separate from the visual interface. Many teams run API tests before UI tests to catch backend problems earlier.

Combining API and UI Testing

A common pattern uses an API request to set up data, then verifies the result appears correctly in the user interface.

cy.request('POST', '/api/products', { name: 'Test Item', price: 10 })
cy.visit('/shop')
cy.contains('Test Item').should('be.visible')

This pattern creates test data quickly through the API, then confirms the visual page reflects that data correctly.

Handling Expected Errors

Some tests intentionally check that an API rejects invalid input correctly.

cy.request({
  method: 'POST',
  url: '/api/products',
  body: { name: '' },
  failOnStatusCode: false
}).then((response) => {
  expect(response.status).to.equal(400)
})

The failOnStatusCode option prevents Cypress from automatically failing the test on an error status, allowing the test to check for that error intentionally.

Key Points

  • The cy.request command sends direct HTTP requests without loading a page.
  • Response objects include status codes, headers, and body data for checking.
  • POST requests let tests create data directly through the API.
  • API tests run faster than full page tests since they skip rendering.
  • The failOnStatusCode option allows testing expected error responses.

Leave a Comment

Your email address will not be published. Required fields are marked *