Is it possible to use just one tool to test everything? Although it may sound like a developer’s daydream, it is almost possible with Cypress, a JavaScript frontend testing framework. Unlike other tools such as Selenium, Cypress can get you started writing tests quickly without needing to add third-party dependencies or packages.
In this tutorial, you will learn how to use Cypress to test an API. You will set up Cypress, write tests for a sample API, and integrate these tests into a CI/CD pipeline using CircleCI. By the end, you’ll have a robust framework for automated API testing that can be easily integrated into your development workflow.
Prerequisites
To follow this tutorial, you will need to have a few things in place:
- Basic knowledge of JavaScript, Git, and GitHub
- Node.js installed on your system (version >= 10.3)
- You can check your version of node by running
node -v
- You can check your version of node by running
- A CircleCI account
- A GitHub account
Using Cypress for API testing
Cypress is a standalone testing tool. To test web applications, it makes HTTP requests on behalf of the web applications as it is executing. While it might appear that Cypress is making these requests from the browser, it actually uses Node.js as a JavaScript engine to make the HTTP requests to the API server. It uses Node.js to return the responses received from the server.
Cypress also exposes the cy.request()
method to make HTTP requests from within the framework. That is the method we will use in this tutorial to test an API using Cypress, rather than a frontend application.
Initializing the directory and setting up Cypress
First, create an empty directory and initialize an empty Node project by running these commands on the terminal:
mkdir testing-apis-with-cypress && cd testing-apis-with-cypress
The first command creates the directory while the second creates a Node.js project with default configurations. We will update the default config later in the tutorial. We will write our tests in the initialized Node project. Next, run:
npm init -y
Running npm init -y
creates a Node project with the default configuration and will not prompt you to customize the contents of the project’s package.json
file. The package.json
file will yield a different result if only npm init
is run, because it will prompt you for the configuration of the Node project properties.
Now that you have an initialized directory, you can install the Cypress framework. Installation of Cypress happens just like installation of any other npm package, so you can install it with either:
npm install cypress
Or:
yarn add cypress
After Cypress has been installed, the next step is initializing the Cypress framework. This process will create the default Cypress directories that you need to write your tests and include packages, if that is required.
In the terminal, run the following command to launch Cypress:
npx cypress open
This will open a new window that will guide your configuration process so that you can start writing your first test. Cypress versions before version 10 are different in appearance, and you can read the changelog for more information.
There is an intro video:
After clicking continue, you’ll see a choice between E2E Testing and Component Testing.
Click on E2E testing, and Cypress will do the configuration under the hood for you. You’ll be prompted to create configuration files, and you can continue with the defaults. You’ll then be prompted to choose a browser, and for our case we will select chrome. We will now get the option to create our first spec.
Because this is the first time, we will be prompted to either select a scaffold example spec or create a new empty spec; for this tutorial, we will create a new empty spec and proceed.
After running our new spec file we should see passing tests in a window similar to the one below.
With this in place, you have just successfully installed and configured Cypress on your chrome browser for end-to-end testing. In the next section, we will setup the URL for our API and start testing.
Getting started with Cypress
For this tutorial, we will use an already sample API that returns a list of users to test our application. To do this though, we first need Cypress to understand what is the API Url that we will be using in our tests (Cypress refers to this as the baseUrl
).
Setting thebaseUrl
Cypress framework has a configuration file cypress.config.js
in the root of the project that is generated by the Cypress initialization process. The cypress.config.js
file stores all the configuration variables that we supply, and this is where we will set our baseUrl
. This is to ensure that we do not need to repeat the entire URL when we are running our tests. The baseUrl
will be set as a configuration variable to a sample API that we’ll use for testing, as shown by the code snippet below in the cypress.config.js
file.
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: "https://reqres.in/api/",
},
});
Setting the run command
Now that we have our test URL ready, we need to create an easy way for us to run our tests using the terminal. To do this, we will add a script in the package.json
file in the scripts section. To achieve this, we will need to add the test
command below to the package.json
file scripts section.
"scripts": {
"test": "npx cypress open"
},
This command tells Cypress to run in non-headless mode and open a browser when executing our tests.
Scripts in the package.json
file automate commands and scripts that you would have had to run on the terminal. Instead you use npm
to execute them while packaging them in a way that is understandable to the program being run.
Writing your first Cypress API test
Remember, Cypress works by using Node under the hood to trigger HTTP requests and route the response back to Cypress to make assertions and to verify that the expected calls were made. In the first test, we will make a GET
request to our sample application to make sure that it actually returns the users as we expect them.
Before we do this, we need to create a directory named api-tests
folder within cypress/e2e
folder. The cypress
folder was automatically generated when Cypress was initialized.
In the api-tests
folder, create the users.cy.js
file, which is where we will write our tests. Here is the awesome bit: Cypress is self-sustaining, so we do not need any other external dependencies to test our APIs.
Open the users.cy.js
file to set up the test on the API GET
request for the users. Add this code:
describe("Users api testing", () => {
it("fetches users - GET", () => {
cy.request("/users?page=2").as("usersRequest");
cy.get("@usersRequest").then((users) => {
expect(users.status).to.eq(200);
assert.isArray(users.body.data, "Users Response is an array");
});
});
});
In this example, Cypress attaches baseUrl
to the cy.request()
method. This method makes a GET request to the sample API endpoint to get a list of users, and validates that the API is being called by the test.
Note: When cy.request()
has not been passed any HTTP request operation, it defaults to a GET request. That is why you do not need to tell the test that you are making an API GET
request.
Executing Cypress API tests
To execute the first test and check that everything is running properly, run the command npm test
in the terminal. We defined the npm test
command earlier in our package.json. The Cypress dashboard will open.
Any added test specs (files) will show up on the Cypress dashboard when we run the command to execute tests. Select the actual test and watch Cypress execute it.
The dashboard shows that test execution was successful and we were able to get all our users from the sample array. Cypress runs in a browser by default, so we can further verify all the elements that were returned from the test.
From the left side of the screen, click the last assertion that shows the returned arrays. This prints the output to the console. You can then right-click on the inspect element on the same window to open the browser developer tools. Click the Console tab to display the array of items that we are asserting in our test. There is a reason to celebrate, because we can verify that our API and our tests are working correctly.
Writing and adding more tests
Now that you are familiar with adding Cypress, you can add more tests. For example, you can test fetching an individual user or even creating a new user on the sample API we are using.
For POST
requests, or any request that isn’t a GET
, you will need to declare the type of HTTP request in the cy.request()
. That is also where to declare any other arguments like the body
for the POST
request that creates a new todo item.
In the next section, you will start the process of automating the test by configuring CircleCI pipeline.
Writing the CI pipeline
Once you have set up the CircleCI pipeline, it is time to add CircleCI to the local project. Start by creating a folder named .circleci
in the root directory. Inside this folder, create a config.yml
file. Add these configuration details to config.yml:
version: '2.1'
orbs:
cypress: cypress-io/cypress@3
workflows:
use-my-orb:
jobs:
- cypress/run:
cypress-command: npx cypress run --e2e
This config uses Circle CI Orbs, which let you easily package everything you need to run your CI. In this case, we’re using a Cypress Orb to simplify and save time on the configuration. You can see the full configuration that the Orb leans on in the documentation, which makes it clear how much setup is abstracted away for us.
Setting up Git and pushing to CircleCI
Before you can start automating your tests, you need to set up CircleCI and connect it to your project. To begin, initialize a Git repository in the project by running the command:
git init
Next, create a .gitignore
file in the root directory. Inside the file, add node_modules
to keep npm generated modules from being added to your remote repository. The next step will be to add a commit with all your work so far, then push your project to GitHub.
If you haven’t already, create a CircleCI account. Connect your account to Github, and create a new organization.
Next, create a new project from the Github repository you just pushed. You’ll need to follow the instructions on the page to connect your repository to CircleCI.
This will start the CircleCI pipeline and automatically run the tests successfully!
Success! All your have tests passed.
Conclusion
In this tutorial, you have set up Cypress and configured it to run API tests. You learned how to set the baseUrl
for testing and configured the directories in the testing framework. You learned to use cy.request()
to make different HTTP operations and how to use the Cypress test runner. Finally, you automated your tests with the help of continuous integration and CircleCI.
I hope you and your team can benefit from what you learned in this tutorial. Enjoy developing your applications!