Integration testing is the process of testing a group of modules as a whole, verifying that they work together as expected. In our field, the "modules" being tested in conjunction can be REST APIs, frontends, mobile apps, etc. In this case we are going to refer to testing apps as a user would do - including a UI/frontend and a backend. These kinds of tests are also called "interaction" tests.
There are many tools that can help us accomplish this objective and one of the most well known ones is Cypress. Cypress basically emulates a browser and executes anything that a user would be able to do, but in an automated way. It allows us to write E2E, Component, Integration and Unit tests and if integrated with a CI provider, Cypress Cloud can also record your test runs for further analysis.
Integrating Cypress into an existing project
If we already have a project and we want to start writing an integration test for it, the first thing we have to do is to include Cypress as a part of its (development) dependencies. We can do that just by running
BASH
or
Once you got the cypress application installed, it can be run from the root of your project with one of the following commands:
This will open the Cypress Launchpad
Another alternative, and also a good practice, is to add this command as a script inside our package.json file:
Now we can invoke this command from the root of our project using npm and accomplish the same result:
In this case we are going to write our first E2E test, where our whole application will be running and we will test that it behaves as intended.
After selecting the E2E testing option, another screen will be displayed with the basic configuration files added by Cypress to run properly, for the moment leave them as they are and continue. Cypress will prompt you to choose one of the compatible browsers found in your system:
In our case we’ll choose Chrome and then click the “Start E2E Testing in Chrome” button to create our first test. The following screen will appear:
Select “Create new empty spec”, then click the “Create Spec” button, and in the following screen click the “Okay, run the spec” button to give it a try.
The new default test will be displayed and will click the “Okay, run the spec” button to give it a try.
In this opportunity we are going to test a register form, to do so, inside your preferred text editor let's open up the newly created test file “cypress/e2e/spec.cyjs” and start modifying it to fulfill our intended test case.
As we can see the test is made of three main enclosures:
Now that we have an idea of how to structure our tests let’s take a look at our applications' home page and start building our first custom Cypress E2E test.
[ For this example, to work properly, remember to have the backend and frontend modules of our project running, otherwise the tests will fail ]
As this is a registered user which accesses only to application, the first thing a user should do in order to access, will be to register itself. So let’s start automating that case.
First to make our test definition more pristine, let's modify the description and the block’s first params and replace them with “Register new user” and “success registration”. Also replace the cy.visit(‘https://example.cypress.io’) with the url where the frontend instance of our application is running. In this case I will use ‘localhost:5173/’.
Now our test should look something like this:
If we save the changes made to the file until now, the only difference will be that the test now navigates to the home page of our application, but doesn’t perform any action or assertion afterwards.
Let’s define the following minimum steps that we have to perform, as a user, in order to get registered:
With these steps in mind let's add the following instructions to our test for steps 1 and 2:
After saving the changes, the test will reload and relaunch itself introducing the new modifications:
cy.get(‘#register-btn’).click() will look up for a html element with an id matching ‘register-btn’ and then perform a click action with the chained command ‘.click()’;
cy.url().should(‘contain’, ‘/register’) will retrieve the current page url and then check that it contains the string ‘/register’ into it.
If no element with id ‘register-btn’ exists or the button redirects the user to a page that’s not under the /register routes, the test will fail.
Now that the user has successfully loaded the register page, let's fill out the form and perform the registration. To do that let’s add the following lines to our file:
We have added some new commands now:
If we save the changes and run the test again. we could see how the user is now redirected to the Registration form, fills in all the required fields and submits the form. Finally it awaits for the API response before ending the test.
As we showed in this step-by-step guide, with the help of Cypress we can automate a desired user flow and its interactions: clicking elements, asserting redirections, fulfilling inputs with values, submitting forms and waiting for the API to respond before moving on.
These were just a subset of the commands that can be used to set our use cases and perform an integration E2E test. At Ensolvers, we use Cypress and other frameworks as well to define automated tests that are daily run via CI pipelines with the aim of ensuring early bug detection and constant quality assurance of the software being built.