Cypress API Testing: A Comprehensive Guide

Master Cypress API testing with this complete guide—learn setup, commands, best practices, and real-world examples to streamline your test automation.

Get Started free
Home Guide Cypress API Testing: A Comprehensive Guide

Cypress API Testing: A Comprehensive Guide

When apps crash, people blame the interface. But developers are aware that most bugs reside deeper in the APIs. They cause flaky behavior, load problems, or complete failure. Manual API checks make release cycles slower. What teams need are speed, confidence, and low-maintenance tests.

Cypress has become a UI testing favorite due to its reliability and speed. But, its API testing features are underutilized.

Cypress can execute GET, POST, PUT, and DELETE requests with built-in assertions and robust chaining.

Overview

Advantages of Cypress for API Testing

  • Unified Testing Framework
  • Real-Time Reload and Debugging
  • Rapid and Compliant Test Run
  • Assertions and Commands Built-In
  • Automatic Waiting Mechanism
  • Parallel Test Execution
  • Simplified Syntax
  • Comprehensive Test Coverage

This guide explains how Cypress makes API testing reliable and fast.

What is an API? (Purpose of API testing)

API – Application Program Interface is a way in which two different software components communicate.

  • For example, you interact with remote devices in BrowserStack from the BrowserStack website with the help of API. It acts as a medium for communication between two different software components.
  • When a product is being developed, you won’t have a UI to validate the front-end part.
  • But with API testing, you can validate the response you will get in the front end when the product is being developed.

Understanding API Testing

API testing is important in modern software development. It tests the functionality, reliability, performance, and security of application programming interfaces (APIs).

APIs play the role of a middleman, enabling various software systems to communicate with one another and exchange information. Testing them ensures they behave as expected under varying conditions, handle errors properly, and maintain performance standards.

Unlike traditional user interface testing, API testing occurs at the message layer, so issues can be caught early. It enables smooth, continuous integration and delivery practices.

With API testing, development teams can identify and correct defects early in the development process. This saves late-stage bug fixing and delivers a seamless user experience. The practice is most useful in agile and DevOps cultures, where rapid iterations and deployments are the norm.

Setting up the Environment

To get started with Cypress, follow the below steps:

1. Create a folder where you would like to store and execute the scripts.

2. Open the terminal and set up the node project with the command, which will create package.json file with default values.

npm init -y

3. Execute the command, from the same folder in the terminal.

npx cypress install

4. Now the installation will be complete, and then the Cypress application will appear on the screen.

For executing Cypress API testing, you don’t need to install any additional packages as Cypress itself has the capacity of handling API requests and responses.

Writing your first Cypress API test

  • To make an API request, Cypress automation provides an inbuilt command called cy.request().
  • With this command, Cypress will make an HTTP request on behalf of the web application and get the response from the API server.
  • When the API request is successful, you will get the response status as 2xx.

Syntax

cy.request(method,URL,body)

In the above command, method, and body are optional but the URL is mandatory.

ArgumentDefinition
methodThis is the type of HTTP method you would like to implement. By default, Cypress makes this request as GET.
URLURL to which you need to send the request
bodyBody to send along with the request
cy.request(options)

In the above command, the argument options should be in the form of object

OptionDefault valueDescription
logtrueWhether it should display the command in command log
urlnullThis is the URL to which you need to make request
methodGETType of HTTP request which you need to request
authnullAuthorization header which needs to send along with the request
bodynullBody of the request
failOnStatusCodetrueWhether to make the script fail for response code other than 2xx and 3xx
followRedirecttrueWhether to follow redirects automatically
formfalseWhether to convert the body values to URL encoded content and set the URL encoded header
encodingutf8This is the type of encoding to be used when serializing the response body. Below are the supported encodings:

ascii, base64, binary, hex, latin1, utf8, utf-8, ucs2, ucs-2, utf16le, utf-16le.

gziptrueWhether to accept the gzip encoding
headersnullAdditional header which needs to be sent.
qsnullQuery paraments to append to the URL of the request.
retryOnStatusCodeFailurefalseThis set the retry ability to Cypress request command. If it is set to true, Cypress will give a retry up to 4 times.
retryOnNetworkFailuretrueRetry ability on network error. This will give a retry up to 4 times.
timeoutresponseTimeoutTime up to which it has to wait for the completion of the command. By default, it will wait up to the time which is mentioned in the config file responseTimeout

Making HTTP Request with Cypress

Make a simple GET request with cy.request() command. You will make a GET request to the following URL – https://www.bstackdemo.com/ with the below piece of code,

describe('template spec', () => {
it('passes', () => {
//Getting response from BrowserStack demo website
cy.request('GET','https://www.bstackdemo.com/')
})
})

You can view the request’s response from the console log of the Cypress runner by inspecting it.

console log of the Cypress runner

Assertions in Cypress API testing

Now, go ahead and try to assert the API response. When you hit the API server with the URL, if you get a response status of 200, you can say that the request you passed succeeded.

Try to assert the response status code with the below piece of code:

 describe('template spec', () => {
it('passes', () => {
//Getting response from browserstack demo website 
cy.request('GET','https://www.bstackdemo.com/').then((response) =>{
//Expecting the response status code to be 200
expect(response.status).to.eq(200)
})
})
})

With this, you will be able to assert whether the response code which you got back is 200 or not.

response code in console log of the Cypress runner

Advanced Cypress API testing

Here is the list of various methods supported by Cypress:

GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE, COPY, LOCK, MKCOL, MOVE, PURGE, PROPFIND, PROPPATCH, UNLOCK, REPORT, MKACTIVITY, CHECKOUT, MERGE, M-SEARCH, NOTIFY, SUBSCRIBE, UNSUBSCRIBE, SEARCH, CONNECT.

But mostly, GET, POST, PUT, DELETE, and PATCH methods will be used. look at their purpose.

MethodPurpose
GETThis method is for getting the list of data / specific data, available from the API server
POSTPOST request is used to create data in the server
PUTPUT is for updating the existing data
PATCHThis method is for updating the data partially
DELETEAs the name implies, it is for deleting the data in target server

Try to execute them one by one, with a help of an external dummy API website – https://dummy.restapiexample.com/

With the below piece of code, you can execute POST, PUT, PATCH and DELETE request and understand it more clearly

describe('template spec', () => {
//This block inserts the data which is mentioned in the body of the request
it('POST request', () => {

cy.request({method: 'POST', url: 'https://reqres.in/api/users', body: {
"name": "Bingo",
"job": "Team lead"
}}).then((response) =>{
//Asserting the status code to be 201 for successful execution
expect(response.status).to.eq(201)
//Asserting the name which you have inserted into
expect(response.body.name).to.eq("Bingo")
//Asserting the status text to confirm whether it is created
expect(response.statusText).to.eq("Created")
})
})

//This block will execute PUT request
it('PUT request', () => {

cy.request({method: 'PUT', url: 'https://reqres.in/api/users/2', body: {
"name": "Angel",
"job": "zion resident"
}}).then((response) =>{
//Asserting the status code to be 200 for successful execution
expect(response.status).to.eq(200)
//Asserting the name which you have inserted into
expect(response.body.name).to.eq("Angel")
})
})

//This block will execute the PATCH request and update the record
it('PATCH request', () => {

cy.request({method: 'PATCH', url: 'https://reqres.in/api/users/2', body: {
"name": "Angel",
"job": "zion resident"
}}).then((response) =>{
//Asserting the status code to be 200 for successful execution
expect(response.status).to.eq(200)
//Asserting the name which you have inserted into
expect(response.body.name).to.eq("Angel")
})
})

//This block will delete the user which exist
it('DELETE request', () => {

cy.request({method: 'DELETE', url: 'https://reqres.in/api/users/2'}).then((response) =>{
//Asserting the status code to be 204 for successful execution
expect(response.status).to.eq(204)
})
})
})

Advanced Cypress API testing

Cypress vs Other API Testing Tools

While Cypress is primarily a frontend testing tool, it offers powerful support for API testing. Here’s how it compares with dedicated API testing tools:

ToolStrengthsLimitations
CypressCombines frontend + API testing in one tool, uses a real browser, easy syntax, great for end-to-end flowsNot ideal for load testing, limited CLI-only API workflows
PostmanExcellent for manual API testing, visual interface, collection runner, and built-in test scriptsNot suited for UI automation, less powerful in CI pipelines
REST AssuredJava-based, good for backend-heavy applications, strong integration with TestNG/JUnitRequires coding knowledge, steeper learning curve
SupertestLightweight, great for Node.js APIs, integrates well with Mocha/ChaiMinimal ecosystem, lacks visual feedback
KarateDSL-based, combines API + UI + performance testing, great for BDD fansHas a learning curve, less popular in large frontend ecosystems

Running Cypress API Tests in CI/CD Pipelines

​Integrating Cypress API tests into CI/CD pipelines ensures consistent validation of your application’s functionality with every code change. This approach enhances reliability, accelerates feedback loops, and supports agile development practices.​

1. Installation and Configuration

Install Cypress as a development dependency:

npm install cypress --save-dev

Add test scripts to your package.json:

"scripts": {

  "test": "cypress run"

}

2. CI/CD Integration

Depending on the documentation of the CI/CD tool you use, configure it to include Cypress in the workflow:

  • GitHub Actions: Utilise the official Cypress GitHub Action to run tests on push or pull request events.​
  • GitLab CI/CD: Configure .gitlab-ci.yml to include Cypress test stages. Use official Cypress Docker images for a consistent environment.
  • CircleCI: Implement Cypress tests using CircleCI Orbs for streamlined configuration
  • Azure DevOps: Integrate Cypress tests by adding npm tasks in your pipeline configuration.
  • Jenkins: Set up Cypress tests within Jenkins pipelines using npm scripts and appropriate plugins.

3. Running Tests in Parallel

Cypress supports parallel test execution to reduce overall testing time. Utilise the –parallel flag in conjunction with the record option and a valid project key:​

npx cypress run --record --key <your_project_key> --parallel

4. Environment Variables and Secrets

Manage sensitive data and environment-specific configurations using environment variables. In CI/CD platforms, set these variables securely to prevent exposure.​

5. Caching and Dependencies

Implement caching strategies for dependencies and Cypress binaries to speed up the pipeline execution. Most CI/CD platforms support caching mechanisms to store and restore dependencies between runs.

Advantages of Cypress for API Testing

Cypress offers several advantages for API testing, making it a preferred choice for many development and QA teams. Its integration capabilities, real-time feedback, and developer-friendly features streamline the testing process. Some of its benefits are:

1. Unified Testing Framework: Cypress supports both frontend and API testing under one umbrella. This allows for easier testing, as teams can write and maintain tests with less effort.

With the same tool used to fulfill various testing requirements, teams can ensure consistency and minimize the overhead of having to deal with various testing environments.

2. Real-Time Reload and Debugging: Cypress offers real-time reloading, whereby tests are instantly updated as one makes changes. This functionality accelerates development and debugging effectiveness with the ability to provide instant feedback on code change.

Cypress further allows pausing and examining app states for effective debugging, thereby making bug-fixing easier.

3. Rapid and Compliant Test Run: Cypress has a high-speed test execution, which reduces flakiness and gives rapid feedback to developers. This is critical in continuous integration and delivery pipelines.

4. Assertions and Commands Built-In: Cypress provides a comprehensive list of built-in assertions and commands specifically for use in API testing.

These simplify test authoring and management so that the tests can be written more directly and easily maintained.

5. Automatic Waiting Mechanism: Cypress has an automatic waiting feature that waits on commands and assertions before proceeding.

This helps decrease the amount of manual waits and timeouts, producing more stable and trustworthy tests.

6. Parallel Test Execution; Cypress allows you to execute tests in parallel, which can accelerate the testing process, particularly for large test suites. This feature is useful in continuous integration scenarios where time efficiency is important.

7. Simplified Syntax: Cypress relies on JavaScript for testing, which most developers are comfortable with.

Its clean syntax and documentation ensure ease of learning, shortening the learning time for new team members.

8. Comprehensive Test Coverage: With Cypress, teams can provide complete test coverage by combining API, UI, and end-to-end tests.

This full-picture strategy extensively tests every area of the application, resulting in high-quality software.

Challenges in Cypress for API Testing

Although Cypress offers numerous advantages when it comes to API testing, it also comes with disadvantages that may restrict its use on specific projects. Acknowledging such limitations is essential in making informed decisions while using Cypress with your test environment.

1. Browser Dependency: Cypress executes within a browser environment even when executing API tests. While useful for frontend testing, this introduces additional overhead for test cases involving the backend exclusively.

A headless or command-line approach would likely be more appropriate in these cases as it would not have the additional resource overhead of the browser.

2. Limited Cross-Browser Support: Cypress only supports a small number of browsers, such as Chrome, Edge, Firefox, etc.

Cypress does not support Safari or Internet Explorer, which could be a problem for highly cross-browser-dependent applications. Test teams with those browsers would need to potentially rule out Cypress from consideration due to its limitations.

3. Limited Mobile Testing Capabilities: Cypress cannot test native mobile applications. While it can also simulate mobile viewports within a browser, it has no means of reaching native mobile features or testing on actual mobile devices and emulators.

This could be a big limitation to those teams that wish to test mobile functionality along with their API workflows.

4. No Multi-Tab or Multi-Window Support: Cypress has no support for testing in multiple browser tabs or windows.

This is a limitation for applications based on multi-tab or multi-window interactions, such as applications requiring testing of features like pop-ups or links to external pages. This limitation can make it harder to test complex user workflows across many browser contexts.

5. JavaScript-Centric Framework: Cypress is technically designed to target JavaScript and TypeScript. While that is good enough for teams that work in those languages, it may not necessarily be ideal for teams that use other languages, such as Python. Such teams may find it more difficult to implement Cypress in their test suites as it involves a learning curve.

6. Performance Impact: Running tests inside a browser is resource-intensive, especially when dealing with large test sets or running tests in parallel.

This can have an impact on performance and make continuous integration pipelines less efficient if tests are run at scale. Groups will want to optimize the test configuration in order to avoid potential slowdowns.

7. Limited Community Support: Compared to more established testing libraries, Cypress boasts a less established community. While active and growing, there are fewer resources, plugins, and support from the community.

This makes development and troubleshooting potentially slower because there may be fewer examples or solutions to refer to when errors occur. Users of Cypress may find that it takes longer to resolve issues or customize the tool to their specific needs.

Best Practices for Cypress API testing

When you have an API call which needs to be called across many test cases, then you can create your own custom command with Cypress and use it across many spec files. For example,

  • First store the API URL as an environment variable to access it across files with Cypress.env() command.
  • To store this URL as a variable, add the below object inside cypress.config.js file,
env: {
myURL: "https://reqres.in/"
}
  • Create a custom command inside /support/commands.js file like below,
//You are creating a custom command named GETrequest which has URL and userDataLink as argument 
Cypress.Commands.add('GETrequest', (url,userDataLink) =>{
//Usual GET request command
cy.request('GET',`${Cypress.env(url)+userDataLink}`)
})
  • You can use this custom command inside you spec file and get the API response stored in a variable.
  • The complete working spec file, will look like below,
describe('template spec', () => {
it('passes', () => {
//Get the API request with URL and user details arguments and store response in a variable named details
cy.GETrequest('myURL',"api/users/2").as('details')
//With cy.get() validating the status code of response
cy.get('@details').its('status').should('eq',200)

})
})

BrowserStack Automate Banner

Real-World examples of Cypress API testing

Go further on testing API, by making an API GET request call to weather API, get their response, and do assertion with it.

For this step, you may need to sign-up for the weather API website, create your own account and get the API access key.

weather API website

Inside cypress.config.js file, paste your access key under an object named env as below,

const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
env: {
access_key: "<your_access_key>"
}
},
});

Then, you can import this access key inside our test script and make an API call with the help of below script,

describe('template spec', () => {
it('passes', () => {
cy.request({method: 'GET', url: 'http://api.weatherstack.com/current', qs: {
//Access key given by the website
access_key: Cypress.env('access_key'),
//Name of the city for which you are viewing temperature
query: "Chennai"
}}).then((response) =>{
//Asserting the status code to be 200 for successful response
expect(response.status).to.eq(200)
//Asserting the location name
expect(response.body.location.name).to.eq('Chennai')
})
})
})

With this above piece of code, you will be able to get the API response, assert the response status code and also assert its location name in the response.

Talk to an Expert

Testing a GraphQL API with Cypress

GraphQL is a query language for API. To test GraphQL API, you will use another external website – star-wars-swapi. By hitting the GraphQL API they provided, you will get the list of Star Wars movies.

Here is the working code:

describe('template spec', () => {
it(GraphQL request, () => {
//Making a POST request to the given URL
cy.request({method: 'POST', url: 'https://swapi-graphql.netlify.app/.netlify/functions/index',
body: {
//Query parameter which needs to be passed for GraphQL
query: `query Query {
allFilms {
films {
title
director
releaseDate
speciesConnection {
species {
name
classification
homeworld {
name
}
}
}
}
}
}`
}
}).then((response) =>{
//Asserting the status code to be 200 for successful response
expect(response.status).to.eq(200)
cy.log(response)
})
})

You will notice that, the only difference which you have between the usual REST API and GraphQL API is the query part. You need to pass the body request as a query.

Conclusion

With the above explanations, you will be able to understand the different methods of API testing, performing assertions for API testing with Cypress, best practices for Cypress API testing, real-world examples of API testing, and performing API testing for GraphQL API.

With BrowserStack Automate, teams can run Cypress-based API tests across 3500+ real device-browser combinations, validating frontend-backend integrations with accuracy and speed. It’s an ideal solution for scaling Cypress API tests without the Cypress Dashboard, while ensuring tests reflect real-world behavior and performance.

Browserstack provides you with a robust infrastructure to test on multiple devices with Cypress for:

Start Cypress Testing

Tags
Automation Testing Cypress

Get answers on our Discord Community

Join our Discord community to connect with others! Get your questions answered and stay informed.

Join Discord Community
Discord