You are currently viewing End to end testing with Cypress

End to end testing with Cypress

It’s been a while since my last blog post and I’ve learned various things in the meantime.
However probably the most useful thing I toyed around with was Cypress for end to end testing.

What is end to end testing?

There are different levels of testing software.
The three you should know definitely are:

  • Unit testing – Is about testing one unit of code in isolation.
    You specify an input and check whether the output matches your expectations.
  • Integration testing – Is about testing interactions between multiple units of code.
    It checks how the API responds invoking all layers from HTTP layer to the database (and back).
  • End to end testing – this is testing as close as possible to a real user interaction.
    But in an automated fashion.

The complexity to write these kind of tests rises with the level: Unit tests are usually the easiest and end to end tests the hardest to write.
Therefore you will only have end to end tests for your happy path and some selected “red” paths. Edge cases are to be caught by integration tests.

This article is about using the Cypress framework for writing end to end tests in a simple way.

Cypress is a JavaScript-based end to end testing framework that is, compared to the de-facto industry standard Selenium very easy to use.

But what makes it different from Selenium?

Well, first of all Selenium executes remote command through the network.
This has implications: Selenium can not know when a resource has done loading and therefore you have to stuff your testing code with all kinds of “waitFor“, “waitUntil“, “executeAfter” stuff.
Basically this is boilerplate code you don’t really want, is of no interest for nobody and adds “noise” to your test code.

Cypress runs in the browser instead. In the same run-loop as your application. No need to care about timing things here. The code is clean and communicates what it does.
And because it operates “within” your application it has native access to everything!

Second: Selenium tests can be written in various programming languages and depends on other tools, but Cypress only in JavaScript.
As the test code is executed in the browser itself there is nothing else required.
You decide if that’s an advantage or not 😉

Third point: While Selenium runs against different browsers, Cypress only supports Chrome.
This point goes to Selenium definitely. If you need to check your website on multiple browsers Cypress is not a choice for you.

But enough background info for now. Let’s get started.

How to do end to end testing with Cypress?

You can simply add it to any Node.js project by using

yarn add cypress

I usually add a script for opening cypress to my package.json:

   "scripts": {
    "test:cypress": "cypress open"
  }

When you run it from the console you’ll see that an electron application starts.

Since you didn’t add any tests under the folder where it usually expects the tests (/cypress/integration) it will add a set of demo tests which you can use to learn and play around.

Cypress UI
This is how the Cypress UI looks like

Clicking on a test suite will run the test: A Chrome window will open and the tests will run in there.

Cypress open and running tests
Clicking on a test suite will run the test. Here you see Chrome controlled by Cypress.

Now let’s have a look at some code:

Cypress action.spec.js source code
Source code of one of the examples provided by default
(Isn’t that really nice to read?)

You see that it is pretty self explanatory:
Before each test it will visit the page at “https://example.cypress.io/commands/actions”.
Then let’s look at one of the scenarios. The one with it(‘.submit() – submit a form’). (The others are folded for a better overview).

It will get the DOM element with the selector “.action-form“, find a descendent DOM element of type “text” and type “HALFOFF” in there.

Then it will submit the form and check the next following DOM element for containing the text:
Your form has been submitted!“.

Note that we only have this fluent code here. No waiting-logic like it would be necessary with Selenium after submitting the form!

This is all cool for development but of course you want to run it headless in your CI pipeline instead of executing it manually.
For that just change the “cypress open” command above to “cypress run“.
You’ll see it runs headless in your terminal and even creates a video for each test suite!
So when something breaks you can watch the video to reproduce the problem.

Terminal output of running headless
Here you see the terminal output of a headless Cypress run.

Summary

In my opinion for teams that can afford testing only for chrome should make use of Cypress because it eases the writing of end to end tests almost to unit test level.
The API is readable for any developer. Yes, it’s JavaScript but syntax-wise I think anyone can get used to it, since it is fluent and you don’t really need to get “under the hood” here.
You’ll need to have an understanding of how websites work of course. But you need that for any kind of end to end testing.

The Thoughtworks Technology Radar lists Cypress with an “Adopt” rating since 04/2019

What’s your opinion?