Codementor Events

Manjunath - Getting Started with End-to-End Tests in React using Cypress

Published Mar 01, 2019
Manjunath - Getting Started with End-to-End Tests in React using Cypress

React, as you already know, is all about components. Unit tests and functional tests are the most popular testing options in React. That's because it's easier to test components in isolation and as a functional units. However, with end-to-end tests, you can make assertions about how a React app renders and the way it responds to a user's interaction.

This article will focus purely on End-to-End testing. We will have a look at why it's not a bad idea to write end-to-end tests in React and then introduce you to the tools to do that.

Why are End-to-End Tests Great?

An end-to-end test is where the complete application is tested from start to finish. This involves making sure that all integrated aspects of an application function together as expected.

End-to-end tests attempt to simulate actual user actions and, therefore, test how a real user would likely use the application.

The E2E test covers those sections of an application that unit tests and integration tests don't necessarily cover. This is because unit and integration tests only pick up a small portion of the application and assess that portion in isolation.

Assuming that these portions of the application work as intended in isolation, developers cannot possibly confirm if they will work together as a complete unit. This is where having a range of end-to-end tests over and above unit and integration tests prove useful. It helps to get a better idea of the entire application as a whole.

End-to-end tests are primarily used to –

  1. Specify the system we are using
  2. Prevent regression and bugs
  3. Perform ongoing and continuous integration.

Additionally, these tests are designed to run as frequently as possible. This is so that they can provide constant feedback and help ensure that our systems remain clean and bug-free from the end user's perspective.

The main idea behind conducting E2E tests is the benefit of an additional layer of a fully automated testing suite. These benefits include an increase in developer velocity and others.

Comparing Cypress with Other Automation Frameworks in React

A browser automation framework is more than a simple simulation of a web browser. To begin with, these frameworks can launch either a full or headless browser.

A headless browser is one without a Graphical User Interface or GUI. These are typically faster and lighter than the usual browsers and make the ideal tool for automated developer testing. They also come with an API that can be used within a user's test code.

These APIs are capable of mimicking a user's browser interactions, capture screenshots, derive the value of inputted fields as well as perform other automation tasks. Three of the commonly used browser automation framework options are compared below.

Selenium Webdriver

Selenium Webdriver is the best option when looking for the safest choice. Of the three framework options discussed here, Selenium Webdriver has been in the market for the most extended period. Being an open source project, it has exceptionally active support and developer community.

Perhaps the best aspect in favor of the Selenium Webdriver is the fact that it is a part of the broader Selenium ecosystem. This ensures that it provides developer bindings not only for JavaScript but also for Java, Python, C#, Ruby, Pearl and PHP languages.

Given the length of time that Selenium Webdriver has been around, it has gathered together a full gamut of features and is the only one of the three discussed here to support all the major web browsers – IE, Chrome, Firefox, Safari, and Edge.

Its builder API makes it simple to configure and launch the browser instance as needed and prescribe the relevant configuration options. It also allows the user to write code that can simulate a range of browser-user interactions like pressing a button or typing text in a text field.

Even though Selenium Webdriver comes with considerable versatility, features, and integration, its popularity is declining given that is much slower to operate when compared to its peers – Puppeteer and Cypress.io.

Puppeteer

Puppeteer is among the newer browser automation frameworks. It has proven to be excellent when mimicking human-like interaction with a browser. Similar to Selenium Webdriver, Puppeteer also simulates a range of browser-user interaction.

Puppeteer can capture screenshots as well as generate PDFs of specific screens. This fact makes it a fantastic choice for users who need to use it for visual-based testing. Its speed is another advantage that developers can benefit from when selecting a testing tool.

Another major USP of Puppeteer is that it is highly integrated with the Chrome browser and all of its developer and debugging tools. This can be put down to the fact that, similar to Chrome; Puppeteer has been developed by Google and is actively supported by the tech giant.

On the flip side, if you end up developing or testing against Safari, Firefox or Edge, Puppeteer will not work for you, and you will need to go with Cypress.

Cypress.io

Cypress.io is an open source, free front end testing tool. Contrary to the two frameworks discussed above, Cypress.io is a complete testing solution. Its primary focus is on performing end-to-end testing of an application's user experience. It does not claim to be a general test automation service.

Perhaps its biggest positive is its lightning speed. Cypress.io can achieve this by actually running inside the browser. It runs in the same execution loop that runs your application source code. This is contrary to Selenium or Puppeteer which run on a separate process than the one that renders the application code.

Cypress.io does not need to support any control protocols that may be required for inter-process communication. This helps in resolving network or system latency that may slow down the sending and receiving of commands and responses.

However, when you critically analyzing Cypress.io, three glaring aspects come to light –

  1. Cypress.io's method of functioning makes it much harder to communicate with backend servers. This means that users may need to install additional modules when using Cypress.io.
  2. Cypress.io does not support the testing of multiple browser tabs
  3. Cypress.io can control only a single browser instance at a time.

In a nutshell, if you need to select a test automation framework, you can choose between Jest or Mocha. But if you need to choose a browser automation framework, you will need to select one of the three popular options discussed above. If you are looking for an efficient, all-in-one solution, Cypress.io is a good choice..

Setting up Cypress

As mentioned earlier, Cypress is a tool that allows users to write their end-to-end tests quickly and more efficiently, and without any of the hassles around setup. It is a fast, reliable and easy testing method for anything that can be executed in a browser.

The following steps should guide you through setting up Cypress on your machine –

Inside the application root folder, we need to add Cypress as a dev dependency -

$ npm install --save cypress

You could also use yarn. We prefer to use NPM over yarn because of the auditing facility and security check offered by NPM. Some of the vulnerabilities discovered recently suggest that open-source packages can be prone to security issues. Npm from version 6 offers vulnerability check by default. If you're concerned about security of your open-source dependencies, you could try code-analysis software like WhiteSource, Snyk, Sonatype Nexus etc.

Readjust the 'scripts' entry in 'package.json' -

"scripts": {
       ...
       "cypress:open": "cypress open"
}

Next, you need to run your server locally, similar to when you are normally developing. Once done, you can open Cypress in a new terminal window -

$ yarn run cypress: open

Cypress will open a popup window after a short while. Here we will be able to access all our tests.

You will see that Cypress has created a new directory called 'cypress' which has the subfolders 'fixtures,' 'integration' and 'support.' You will also notice that Cypress has added an empty 'cypres.json' config file.

As we will probably need to access the root path often during the duration of the tests, it is a general suggestion to abstract it to the settings file. To do this, you can open the 'cypress.json' file, and include a new entry containing the key 'baseUrl' and the URL as a value –

{
  "baseUrl": "http://localhost:3000"
}

Conclusion

To summarize, testing with Cypress is quick, efficient and fun. The setup process almost non-existent, developing assertions is simple, and the Graphical User Interface is second to none.

Users can easily debug all the steps involved, and as it launches as an Electron app, users can also gain access to developer tools in a bid to learn more about each action as it is executed.

Discover and read more posts from Manjunath
get started
post comments1Reply
Siddharth RoyChoudhury
5 years ago

Liked your post, any thoughts on using TDD approach during e2e.