DevQAExpert

API Testing with Cypress Setup and Execution 

 Testing APIs is an essential component of software development. The application programming interfaces (APIs) are made sure to live up to expectations in terms of functionality, dependability, performance, and security. Today, we’ll look at how to use Cypress, a well-liked end-to-end testing framework, to do API testing. We shall also examine the various claims made by Cypress.

Cypress Setup

 To use Cypress for API testing, we need to install and configure it:

Copy 

// Install Cypress
npm install cypress –save-dev

// Initialize Cypress
npx cypress open

This will install Cypress locally and open up the Test Runner. We can then configure Cypress for API testing by adding the following to cypress.json: 

{
  “baseUrl”: “http://localhost:3000”,
  “requestTimeout”: 30000,
  “responseTimeout”: 30000,
  “viewportWidth”: 1000,
  “viewportHeight”: 660,
  “video”: false,
  “retries”: {
    “runMode”: 2,
    “openMode”: 0
  }
}

 Here we have set a base URL, increased timeouts, disabled videos, and enabled retries for run mode.

 

Writing API Tests

Now we can start writing our API tests in Cypress. Tests will go into the integration/api folder.

Let’s test a simple REST API for a “users” resource. We’ll test the following endpoints:

  • GET /users
  • GET /users/:id
  • POST /users
  • PUT /users/:id
  • DELETE /users/:id

First we’ll create a api/users.spec.js file and import cy from Cypress: 

/// <reference types=”cypress” />

import { cy } from ‘cypress’;

GET /users

To test the GET /users endpoint, we can make a simple GET request and assert the response: 

it(‘gets users’, () => {
  cy.request(‘GET’, ‘/users’)
    .its(‘body’)
    .should(‘be.an’, ‘array’);
});

 This makes a GET request to /users and asserts the response body is an array.

 

 GET /users/:id

 To test GET for a single user resource, we can pass an ID parameter: 

it(‘gets a user’, () => {
  cy.request(‘GET’, ‘/users/1’)
    .its(‘body’)
    .should(‘be.an’, ‘object’)
    .and(‘deep.equal’, {
      id: 1,
      name: ‘John Doe’
    });
});

 Here we assert the response contains the expected user object.

 

 POST /users

 To test creating a new user, we can make a POST request:


it(‘creates a new user’, () => {
  cy.request(‘POST’, ‘/users’, {
    name: ‘Jane Doe’,
    email: ‘jane@test.com’
  })
    .its(‘body’)
    .should(‘deep.equal’, {
      id: 3,
      name: ‘Jane Doe’,
      email: ‘jane@test.com’
    });
});

 We pass the new user data in the request body and assert the response contains the new user object.

 

PUT /users/:id

For updating an existing user, we can make a PUT request: 

it(‘updates a user’, () => {
  cy.request(‘PUT’, ‘/users/1’, {
    name: ‘Johnathan Doe’
  })
    .its(‘body’)
    .should(‘deep.equal’, {
      id: 1,
      name: ‘Johnathan Doe’
    });
});

 Here we pass just the name in the body to update that field for the user.

 

DELETE /users/:id

Finally, to test deleting a user we can make a DELETE request: 

it(‘deletes a user’, () => {
  cy.request(‘DELETE’, ‘/users/1’)
    .its(‘body’)
    .should(‘deep.equal’, {});
});

 On delete we expect an empty response body.

And that covers the basic CRUD operations! Each endpoint can be tested in isolation by stubbing responses or leveraging test data setup/teardown.

 

Executing the Tests

To run the tests head to the Test Runner and select the api folder. Cypress will run through each test making real network requests and assertions against the responses.

We can also run the tests headlessly from the command line:

 

cypress run –spec cypress/integration/api/*

This will execute the tests and output the results to the console.

 

Assertions

Cypress provides a variety of assertions we can make against responses, here are some useful ones:

Status Code

cy.request(…).its(‘status’).should(‘eq’, 200);

Response Body 

cy.request(…).its(‘body’).should(‘deep.equal’, {…});

Response Headers 

cy.request(…).its(‘headers’).should(‘have.property’, ‘content-type’, ‘application/json’);

Response Time 

cy.request(…).should((response) => {
  expect(response.duration).to.be.below(500)
});

Schema Validation 

cy.request(…).then(response => {
  expect(response.body).to.have.schema(schema);
});

Stubbing Responses 

cy.intercept(‘GET’, ‘/users’, { fixture: ‘users.json’ }).as(‘getUsers’);

cy.request(…).then(() => {
  cy.wait(‘@getUsers’).its(‘response.body’) // Stubbed response
});

 

This allows you to easily test various scenarios and edge cases.

 

Conclusion

Cypress provides a great way to test web APIs with its simple API, built-in assertions, and ability to control network traffic. While it lacks some features of dedicated API testing tools, it enables testing APIs in isolation or as part of an integrated frontend/backend workflow. Overall it’s a handy tool to have in the testing toolbox!