API Testing with Cypress: A Complete Guide

Aswani Kumar - Sep 27 - - Dev Community

Introduction

Cypress is widely known for its end-to-end testing capabilities, but it’s also a powerful tool for testing APIs. API testing is an essential part of ensuring the reliability, performance, and security of modern web applications, as many applications today heavily depend on backend services and APIs. This post will walk you through the basics of API testing using Cypress, including setting up API tests, making requests, validating responses, and automating the process.

Why Use Cypress for API Testing?

  1. Built-in Features: Cypress has built-in capabilities for making HTTP requests, assertions, and managing asynchronous tests.
  2. Easy Integration: You can easily integrate API tests into your existing Cypress test suite, alongside your UI tests.
  3. Great Developer Experience: Cypress offers a user-friendly interface, fast feedback, and real-time debugging.
  4. Automation: You can automate API tests in your CI/CD pipeline, ensuring that APIs are consistently tested with every deployment.

Getting Started with API Testing in Cypress

If you already have Cypress installed for end-to-end testing, you’re ready to start API testing. If not, follow the installation steps below.

Step 1: Install Cypress

npm install cypress --save-dev
Enter fullscreen mode Exit fullscreen mode

Once installed, you can run Cypress with the following command:

npx cypress open
Enter fullscreen mode Exit fullscreen mode

Step 2: Setting Up Your First API Test
Cypress provides a cy.request() method that you can use to send HTTP requests. Here’s a basic example of testing an API that returns a list of users:

describe('API Testing with Cypress', () => {
  it('should retrieve a list of users', () => {
    cy.request('GET', 'https://jsonplaceholder.typicode.com/users')
      .then((response) => {
        // Validate the status code
        expect(response.status).to.eq(200);

        // Validate the response body
        expect(response.body).to.have.length(10);
        expect(response.body[0]).to.have.property('name');
      });
  });
});
Enter fullscreen mode Exit fullscreen mode

In this example, we’re testing a GET request to retrieve a list of users. Cypress validates the response status code and checks that the response body contains 10 users.

Common HTTP Methods in API Testing

Here’s how you can perform common HTTP requests like GET, POST, PUT, and DELETE in Cypress.

GET Request
GET requests are used to retrieve data from the server. For example:

cy.request('GET', 'https://jsonplaceholder.typicode.com/posts/1')
  .then((response) => {
    expect(response.status).to.eq(200);
    expect(response.body).to.have.property('id', 1);
  });
Enter fullscreen mode Exit fullscreen mode

POST Request
POST requests are used to create new resources on the server. Here’s how to test a POST request:

cy.request('POST', 'https://jsonplaceholder.typicode.com/posts', {
  title: 'New Post',
  body: 'This is the content of the new post.',
  userId: 1
})
  .then((response) => {
    expect(response.status).to.eq(201);
    expect(response.body).to.have.property('title', 'New Post');
  });
Enter fullscreen mode Exit fullscreen mode

PUT Request
PUT requests are used to update existing resources. Example:

cy.request('PUT', 'https://jsonplaceholder.typicode.com/posts/1', {
  id: 1,
  title: 'Updated Post Title',
  body: 'Updated content',
  userId: 1
})
  .then((response) => {
    expect(response.status).to.eq(200);
    expect(response.body).to.have.property('title', 'Updated Post Title');
  });
Enter fullscreen mode Exit fullscreen mode

DELETE Request
DELETE requests are used to remove resources. Example:

cy.request('DELETE', 'https://jsonplaceholder.typicode.com/posts/1')
  .then((response) => {
    expect(response.status).to.eq(200);
  });
Enter fullscreen mode Exit fullscreen mode

Advanced API Testing Techniques

Once you have mastered basic API requests, you can move on to more advanced API testing techniques, such as handling authentication, testing API failures, and chaining API calls.

Handling Authentication
Some APIs require authentication via tokens or API keys. Cypress can handle authentication by setting custom headers. For example:

cy.request({
  method: 'GET',
  url: 'https://api.example.com/protected',
  headers: {
    Authorization: `Bearer ${Cypress.env('auth_token')}`
  }
})
  .then((response) => {
    expect(response.status).to.eq(200);
  });
Enter fullscreen mode Exit fullscreen mode

Here, the Authorization header is used to send a token along with the request.

Testing API Failures
It’s essential to test how your API behaves when something goes wrong, such as invalid inputs or missing resources. For example, testing a 404 error:

cy.request({
  method: 'GET',
  url: 'https://jsonplaceholder.typicode.com/posts/9999',
  failOnStatusCode: false
})
  .then((response) => {
    expect(response.status).to.eq(404);
  });
Enter fullscreen mode Exit fullscreen mode

By setting failOnStatusCode: false, Cypress won’t fail the test automatically for non-2xx responses, allowing you to validate error responses.

Chaining API Calls
Sometimes, you need to chain multiple API calls together, for example, creating a resource and then using it in a subsequent test:

cy.request('POST', 'https://jsonplaceholder.typicode.com/posts', {
  title: 'Post for chaining',
  body: 'Chained post content',
  userId: 1
}).then((postResponse) => {
  cy.request('GET', `https://jsonplaceholder.typicode.com/posts/${postResponse.body.id}`)
    .then((getResponse) => {
      expect(getResponse.body).to.have.property('title', 'Post for chaining');
    });
});
Enter fullscreen mode Exit fullscreen mode

In this example, the POST request creates a new post, and the GET request retrieves that post based on the ID returned from the first call.

Automating API Tests in CI/CD Pipelines

To ensure the stability of your APIs, it’s crucial to run your API tests as part of your Continuous Integration/Continuous Deployment (CI/CD) pipeline. Cypress can be easily integrated into CI/CD tools like Jenkins, GitHub Actions, or Travis CI.

Here’s an example of a GitHub Actions workflow that runs Cypress tests on every push:

name: CI

on:
  push:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14'

      - name: Install dependencies
        run: npm install

      - name: Run Cypress tests
        run: npx cypress run
Enter fullscreen mode Exit fullscreen mode

This workflow ensures that API tests are automatically executed every time code is pushed to the main branch.

Best Practices for API Testing with Cypress

To ensure that your API tests are reliable, maintainable, and efficient, follow these best practices:

  1. Use Environment Variables: Store sensitive data like API keys, tokens, or base URLs in environment variables.
  2. Mock Responses Where Necessary: If you don’t want to hit the real API every time, mock the API responses using cy.intercept().
  3. Handle Rate Limits: If your API has rate limits, make sure your tests handle them appropriately by adding retries or delays between requests.
  4. Keep Tests Independent: Ensure that each API test is independent of the others, so they can be run in any order without dependency issues.
  5. Focus on Edge Cases: Test both the happy path and edge cases (e.g., invalid inputs, large data sets, rate limiting) to cover all potential scenarios.

Conclusion

API testing is an essential part of ensuring that your application works seamlessly, even when it relies on external services or backend APIs. Cypress provides a simple yet powerful way to test APIs alongside your UI tests, making it an excellent choice for developers working with modern JavaScript applications. By leveraging features like cy.request(), assertions, and CI/CD integration, you can build a robust and reliable API test suite that catches issues early and ensures the quality of your APIs.

Start testing your APIs with Cypress today, and improve your development workflow with automated, reliable tests!

. . . . . . . . . . . . . . . . . . . . . . . . . .