API Testing With Cypress
Cypress is a great tool for testing applications, including UI and API testing. This guide covers how to use Cypress for API testing.
Join the DZone community and get the full member experience.
Join For FreeIs it possible to test everything using a single tool? Seems like a dream, but I would say it is almost possible with Cypress, a JavaScript frontend testing framework. Cypress is primarily designed for end-to-end testing of web applications, which includes both the frontend user interface (UI) and the backend API interactions.
With Cypress, you can write tests that cover the entire application flow, from interacting with the UI elements to making API requests and validating the responses. This makes Cypress a versatile tool that allows you to test the integration between the UI and the API.
In this tutorial, I will guide you through how we can use Cypress for API testing.
Categories of API Testing
API testing is a type of software testing that focuses on verifying and validating the functionality, reliability, performance, and security of application programming interfaces (APIs). APIs enable communication and data exchange between different software systems, allowing them to interact and share information.
API testing involves testing the various aspects of an API, including its endpoints, input/output data, error handling, and integration with other systems. It ensures that the API behaves as expected, follows the defined specifications, and meets the requirements of the applications or services that rely on it.
APIs Can Be Categorized Into Different Types
- Web APIs: These are APIs exposed by web services over HTTP or HTTPS protocols. They are often used for data exchange in a client-server architecture.
- REST APIs: Representational State Transfer (REST) APIs are a type of web API that follows a set of architectural principles. They use HTTP methods like GET, POST, PUT, and DELETE to perform operations on resources.
- SOAP APIs: Simple Object Access Protocol (SOAP) APIs use XML-based messages over protocols like HTTP, SMTP, or others for communication. They are typically used in enterprise applications.
- GraphQL APIs: GraphQL is a query language for APIs that allows clients to request and retrieve specific data they need, reducing over-fetching or under-fetching of data.
Tools Available for REST API Testing
There are several tools available for API testing, each with its own set of features and capabilities. Here are some popular tools for API testing:
- Cypress: Cypress is a JavaScript-based end-to-end testing framework with a focus on web applications. While it excels in UI testing, it can also be used for API testing using its cy.request() command.
- Playwright: Playwright provides a JavaScript API for making HTTP requests, enabling you to send API requests, handle responses, and perform assertions. Playwright's multi-browser support and cross-platform compatibility make it a versatile choice for API testing in a web context.
- Postman: Postman is a widely used API testing tool that provides a user-friendly interface for designing, testing, and documenting APIs. It allows you to send requests, set headers, handle authentication, and validate responses. Postman also supports test automation and offers features like test collections, environments, and reporting.
- RestAssured: RestAssured is a Java library specifically designed for API testing. It provides a fluent and expressive syntax for writing tests and assertions. RestAssured simplifies the handling of request and response specifications, authentication, and validation of response data.
- Karate: Karate is an open-source API testing tool built on top of Cucumber and Gatling. It provides a unified framework for API testing, mocking, and performance testing. Karate uses a simple syntax that combines test case definition, request specification, and assertions in a single feature file.
- SoapUI: SoapUI is a specialized tool for testing SOAP and REST APIs. It supports WSDL and Swagger specifications, allowing you to import API definitions and generate tests automatically. SoapUI offers features like test case creation, assertions, security testing, and performance testing.
Why Cypress for REST API Testing?
Cypress is primarily known as a frontend testing framework but can also be used effectively for API testing.
Here are some reasons why Cypress can be a good choice for API testing:
- Easy setup and integration: Cypress provides a seamless and straightforward setup process, allowing you to start writing API tests quickly. It is built specifically for JavaScript frontend developers, so if you are already familiar with JavaScript, getting started with Cypress for API testing is relatively easy.
- Unified testing framework: Cypress allows you to use a single testing framework for both frontend and API testing. This can be advantageous as it reduces the need to learn and manage multiple testing tools.
- Integration with frontend tests: If you are already using Cypress for frontend testing, using it for API testing as well can provide better integration and consistency across your test suite. You can combine API tests with frontend tests to cover end-to-end scenarios and ensure smooth interactions between the UI and the API.
- Built-in assertions and helpful API: Cypress offers a comprehensive set of built-in assertions and a user-friendly API for making API requests and performing assertions on the responses. This makes it easy to validate API responses, assert on status codes, response data, headers, and more.
- Test Data and Mocking: Cypress provides mechanisms for managing test data and mocking API responses. You can use fixtures to load test data from external files, create custom Cypress commands to encapsulate API-related logic, and use tools like cy.route() or cy.intercept() to stub or intercept network requests and simulate specific API responses.
How Cypress Executes API Test Cases Internally
Below is a detailed explanation of how Cypress executes API test cases internally. Cypress uses Node.js as an engine to make HTTP requests to the API server.API server responds to the request, and Cypress receives the response through Node.js and can perform assertions or other actions based on the response data.
Below are the steps for how API test cases are executed in Cypress:
Test Initialization
- When you run API test cases in Cypress, it initializes the test execution environment.
- Cypress loads its core library, plugins, and other dependencies required for API testing.
Test File Execution
- Cypress reads the API test file(s) specified in the test runner.
- It parses the test file(s) to identify the API test cases written using Cypress's API syntax.
- Cypress organizes the test cases and their associated commands for execution.
- Cypress launches a browser instance (headless or interactive) using its browser automation capabilities.
- The test cases and their commands are executed within this browser instance.
Command Execution and Interception
- Cypress intercepts API requests made by the test cases using its command interception mechanism.
- When a cy.request() command is encountered, Cypress intercepts the request before it reaches the actual server.
Request Simulation and Response Capturing
- Cypress simulates the intercepted request internally, generating a simulated request object with all the relevant details.
- It captures the response, including the status code, headers, and response body.
Response Validation and Assertions
- After capturing the response, Cypress compares it against the expected values defined in the test case.
- Cypress provides built-in assertion methods (should(), expect(), etc.) to validate different aspects of the response.
Test Reporting
- During the test execution, Cypress collects information about the executed commands.
- The test report is displayed within the Cypress Test Runner interface, providing visibility into the test results and facilitating troubleshooting.
What Is cy.request()?
Cypress leverages the cy.request() command to send HTTP requests to the API server. The cy.request() is a command provided by Cypress that allows you to send HTTP requests and interact with APIs directly within your test cases.
Here are the different variations of the cy.request() command in Cypress:
cy.request(url): This variation sends a GET request to the specified URL.
cy.request(url, body): This variation sends a POST request to the specified URL with the provided request body.
cy.request(method, url): This variation allows you to specify the HTTP method (e.g., GET, POST, PUT, DELETE) along with the URL.
cy.request(method, url, body): This variation sends a request with the specified HTTP method, URL, and request body.
cy.request(options): This variation allows you to pass an options object with a detailed configuration for the request.
API Methods
GET, POST, PUT, and DELETE are the four most common HTTP methods used in REST APIs. They correspond to the CRUD (create, read, update, delete) operations on resources.
- GET: Used to retrieve data or read a resource from the server.
- POST: Used to create a new resource on the server.
- PUT: The PUT method is used to update or replace an existing resource on the server.
- DELETE: The DELETE method is used to delete a specified resource on the server.
Some Commonly Used HTTP Response Codes in REST
- 200: OK: The request was successful, and the server returned the requested data.
- 201: Created: The request was successful, and a new resource was created as a result (typically in response to a POST request). The response will include the URL to access the newly created resource in the Location header.
- 204: No Content: The request was successful, but the response does not contain any content (typically in response to a DELETE request).
- 304: Not Modified: The requested resource has not been modified since the last request. This is commonly used in response to a GET request with conditional headers.
- 400: Bad Request: The request was malformed or could not be understood by the server. This could be due to missing or invalid parameters, incorrect JSON format, etc.
- 401: Unauthorized: The request requires user authentication. The user must provide valid credentials (such as a valid token or username/password) to access the resource.
- 403: Forbidden: The authenticated user is not allowed to access the requested resource. This could be due to insufficient permissions.
- 404: Not Found: The requested resource could not be found on the server.
- 422: Unprocessable Entity: The server understands the request, but the provided data violates some validation rules (e.g., missing required fields or invalid field values).
- 500: Internal Server Error: An unexpected error occurred on the server, indicating a problem with the server's configuration or code.
Some Examples of Different API Methods
Pre-requisites:
- Install Node.js from Node.js.
- Install Cypress from Cypress.io.
- We will be using Go Rest APIs for demo purposes.
Let's take some examples to automate the API endpoint using Cypress for the site.
POST Method
POST method is used to send data to a server to create/update a resource.
it('POST API Automation Using GoRest API', () => {
const user = {
name: 'John Doe',
email: "johndoe123"+randomNumber+"@example.com",
gender: 'male',
status: 'active',
};
cy.request({
method: 'POST',
url: 'https://gorest.co.in/public/v1/users',
headers: {
Authorization: 'Bearer <Enter token here >,
},
body: user,
}).then((response) => {
userId=response.body.data.id
expect(response.status).to.equal(201);
expect(response.body.data.name).to.equal(user.name);
expect(response.body.data.email).to.equal(user.email);
});
});
Here's a breakdown of the code:
- The code defines a test case using the 'it' function. The test case name is not provided in the snippet.
- The 'user' object is defined with properties such as name, email, gender, and status. The 'email' property seems to include a random number concatenated to a base email address.
- The 'cy.request' function is used to send a POST request to the specified URL.
- The 'Authorization' header is included in the request, but the token value is missing. You would need to replace '<Enter token here >' with the actual authorization token for the request to work correctly.
- The 'body' property of the request is set to the user object, which contains the data for creating a new user.
- The 'then' method is used to handle the response from the API request.
- Inside the response handler, the userId variable is assigned the value of the newly created user's ID from the response body.
- Assertion statements are used to verify the response status, name, and email of the created user.
NOTE: A bearer token can be generated from this link.
GET Method
In the GET method The cy.request function is used to send a GET request to the specified URL: ". The ${userId} is a placeholder that likely refers to the user ID obtained from a previous API call.
it('GET API Automation Using GoRest API', () => {
cy.request({
method: 'GET',
url: 'https://gorest.co.in/public/v1'+`/users/${userId}`,
headers: {
Authorization: 'Bearer <Enter token here>,
},
}).then((response) => {
expect(response.status).to.equal(200);
expect(response.body.data.name).to.equal('John Doe');
expect(response.body.data.gender).to.equal('male');
});
});
PUT Method
The PUT method is used to update the existing data. The cy.request function is used to send a PUT request to the specified URL: '. The ${userId} is a placeholder that likely refers to the user ID obtained from a previous API call.
it('PUT API Automation Using GoRest API', () => {
const user = {
name: 'Time Cook',
email: "TimCook123"+randomNumber+"@example.com",
gender: 'male',
status: 'active',
};
cy.request({
method: 'PUT',
url: 'https://gorest.co.in/public/v1'+`/users/${userId}`,
headers: {
Authorization: 'Bearer <Enter token here>,
},
body: user,
}).then((response) => {
expect(response.status).to.equal(200);
expect(response.body.data.name).to.equal(user.name);
expect(response.body.data.email).to.equal(user.email);
});
});
DELETE Method
The DELETE method is used to delete the created record. In the below code, you can see we have used (${userId}, which we want to delete, and the user ID obtained from a previous API call.
it('DELETE API Automation Using GoRest API', () => {
cy.request({
method: 'DELETE',
url: 'https://gorest.co.in/public/v1'+`/users/${userId}`,
headers: {
Authorization: 'Bearer <Enter token here>,
},
}).then((response) => {
expect(response.status).to.equal(204);
});
});
Execution Report of Test Cases
Run the command' yarn cypress open' test cases to start executing in cypress runner.
Below the execution report, all API endpoints are executed successfully.
Execution report of POST and GET method.
Execution report of PUT and DELETE method.
Wrapping Up
API testing with Cypress offers a powerful and efficient way to validate the functionality, performance, and reliability of your API endpoints. By adopting Cypress for API testing, you can enhance the quality of your applications and deliver a seamless experience to your users.
Opinions expressed by DZone contributors are their own.
Comments