Testing a React App With Cypress

In short

Cypress, an open-source testing tool, promises fast, easy, and reliable end-to-end tests for anything in a browser. This article walks through integrating Cypress into a React Native project, testing features like sign-in and sign-out, and leveraging custom commands for efficiency. With minimal setup, detailed test insights, and a user-friendly GUI, Cypress aims to make testing a more enjoyable experience.

Cypress is open source now

Two weeks ago, Cypress was open-sourced and made available to everyone.

Cypress is a tool, that (allegedly) lets you write your end to end tests faster, and with minimum to none setup.

Fast, easy and reliable testing for anything that runs in a browser.

Let’s give it a try and verify if that’s true!

We will integrate Cypress with one of our projects — Eedi. Eedi is a fantastic educational platform for UK teachers, students and their parents. It is crucial, that anyone who uses it, have nice and smooth experience while browsing, and that all works as expected.

Cypress setup

Inside our application root folder, let’s add Cypress as a dev dependecy:

<rte-code>$ yarn add --dev cypress<rte-code>

Adjust the <rte-code>"scripts"<rte-code> entry in <rte-code>package.json<rte-code>:

Run your server locally, just like when normally developing, and then, in new terminal window lets open Cypress:

<rte-code>$ yarn run cypress:open<rte-code>

yarn run cypress

After a while, Cypress should open and we should see a window pop up.

Here we have access to all our tests, there’s even one provided out of the box!

Cypress have created new directory <rte-code>cypress<rte-code> with subfolders <rte-code>fixtures<rte-code>, integration and <rte-code>support<rte-code>. It also added empty <rte-code>cypress.json<rte-code> config file.

Since we will be accessing our root path often, it’s a good practice to abstract it to settings file. Open <rte-code>cypress.json<rte-code> file, and add an new entry with key <rte-code>baseUrl<rte-code> and url as a value:

In the <rte-code>example_spec.js<rte-code> file we can see ‘Kitchen Sink Tests’ that can come in handy when we want to browse some common testing scenarios. But let us write our own tests for now.

Testing sign-in

Signing in is one of most important features of any app. If it’s done poorly, users won’t be able to see the rest of our work, and there’s no point in doing anything else.

Create a new file <rte-code>login_spec.js<rte-code>. Here we will test all our logic regarding signing in.

Let’s go, and write our first test — let’s check if happy path is working as expected:

Now, go to Cypress app and select test that we’ve just created. It should run all tests in a file, and we can watch how they perform:

gif showing how it performs with cypress

At the left pane of test runner, we can see all actions performed by Cypress, elements found and redirects made by browser. We can also use nice time travel feature and inspect every single step of our tests.

Let’s break something! Change line 12 of the test:

failing test

It fails. And that’s good, we have established that happy path is indeed happy. Cypress provides us with detailed stack trace — what went wrong and where it happened.

Add some more cases:

  • unsuccessful log-in action should yield error message, and
  • unauthorized user should not be able to visit restricted URLs.

After we save the test file, Cypress should re-run all tests:

Testing sign-out

Next feature to cover is logout action. We would want to establish that user can sign out from our app correctly. Sounds easy, right?

But let’s think about it for a second… In order to log out, we need to be logged in in a first place, right? Should we reuse the code from the previous test, and then add some more logic to it? Sounds silly, we are developers, we can do better!

Cypress, comes with another handy feature — commands. They allow us to create our own custom actions that can be reused in any tests. And since most scenarios should be written for logged users, this action is perfect candidate for a custom command.

Open <rte-code>commands.js<rte-code> file located in the <rte-code>support<rte-code> folder. Cypress provides us with some examples, and there’s even a stub of a login command already there!

Enhance this login command with our custom behavior, but first let’s think about what we want to do.

We have tested logging in already, haven’t we? So there’s really no point in repeating the same steps with each and every test we will write next. We can even read it in the Cypress docs:

Fully test the login flow — but only once!

And further in the same guide:

Do not use your UI to login before each test.

So what can we do?

We can make direct network request to our backend service using <rte-code>cy.request()<rte-code> to log in, and then proceed as we normally would. Here’s what it looks like:

Now, inside every test, we can call <rte-code>cy.login('username','password')<rte-code> and it should perform login action without engaging UI. We are ready to test logout actions. Create <rte-code>logout_spec.js<rte-code> and add some assertions:

Watch them fail. Then fix lines 14 and 20 <rte-code>(changefirst()<rte-code> to <rte-code>last()<rte-code> and <rte-code>cy.visit('log-out')<rte-code> to <rte-code>cy.visit('logout')`<rte-code>and watch how tests pass:

gif showing how tests pass

Summary

In short — writing tests with Cypress was real fun.

As advertised, setup is close to none, writing assertions is easy and feels natural, and GUI is, well, awesome! You can time travel, debug all steps, and since it all launches as an Electron app, we can even access developer tools to learn more about each action that happens.

The web has evolved. Finally, testing has too. Let’s all write some tests, and may the force be with you!

Latest update:
November 6, 2017

FAQ

No items found.
React Galaxy City
Get our newsletter

By subscribing to the newsletter, you give us consent to use your email address to deliver curated content. We will process your email address until you unsubscribe or otherwise object to the processing of your personal data for marketing purposes. You can unsubscribe or exercise other privacy rights at any time. For details, visit our Privacy Policy.

Callstack astronaut
Download our ebook

I agree to receive electronic communications By checking any of the boxes, you give us consent to use your email address for our direct marketing purposes, including the latest tech & biz updates. We will process your email address and names (if you have entered them into the above form) until you withdraw your consent to the processing of your names, or unsubscribe, or otherwise object to the processing of your personal data for marketing purposes. You can unsubscribe or exercise other privacy rights at any time. For details, visit our Privacy Policy.

By pressing the “Download” button, you give us consent to use your email address to send you a copy of the Ultimate Guide to React Native Optimization.