Cypress

to build your E2E test suite

Using

Vitor Fernandes

github.com/vmlf01

 

Fullstack Developer at

KWAN + Toptal

 

Angular PT organizer

 

Angular/React

Node.js

.Net

Overview

Overview

Cypress is a next generation front-end testing tool

that can test anything that runs in a browser.

Overview

Open-source MIT License

14K+ GitHub Stars

615K+ npm weekly downloads

cypress

CLI Test Runner

Desktop App

Dashboard SaaS

Overview

The Cypress Test Runner runs in the context of the browser and uses the browser's automation APIs.

 

Cypress currently supports Electron or Chrome.


Under the hood, Cypress uses Mocha + Chai + Sinon,

so its syntax is very familar for most JS developers.

The Test Runner

Features

  • Time Travel
  • Automatic Waiting and Assertion Retry
  • Spies, Stubs and Clocks
  • Fixture management
  • Network Traffic Control
  • Parallel Execution
  • Screenshots and Videos

Using Cypress

Adding cypress

Cypress file structure

Running cypress

Selectors

Cypress uses jQuery-like selectors

cy.get(".action-form")

    .find('[type="text"]')

    .type("HALFOFF");

Assertions

Cypress uses Chai assertions. Common assertions include `exist`, `equal`, `deep.equal`,`have.length`, `contain`, `match`, `have.attr`, `have.class`

cy.get(".action-form")

    .submit()

    .next()

    .should("contain", "Your form has been submitted!");

Retriability

Cypress wraps all DOM queries with retry-and-timeout logic that better suits how real web apps work.

cy.get(".action-form")

    .submit()

    .next()

    .should("contain", "Your form has been submitted!");

Execution queue

Cypress commands don’t do anything at the moment they are invoked, but rather enqueue themselves to be run later.

cy.get(".action-form")

    .submit();

 

cy.get(".action-form")

    .next()

    .should("contain", "Your form has been submitted!");

Network requests

Cypress allows you to make network requests or stub network responses.

// make a POST request to server

cy.request(

    "POST",

    "http://localhost:8888/users/admin",

    { name: "Jane" }

);

 

cy.server(); // enable response stubbing

cy.route({

    method: "GET", // Route all GET requests

    url: "/users/*", // that have a URL that matches '/users/*'

    response: [] // and force the response to be: []

});

Integrating with Angular

  • Run Angular and Cypress in parallel
    • separate command lines
    • npm concurrently
    • npm npm-run-all
  • Nrwl Nx
    • already includes integration to run cypress

(https://github.com/mysticatea/npm-run-all)

(https://github.com/kimmobrunfeldt/concurrently)

Cypress best friend

https://github.com/testing-library/cypress-testing-library

My Story

How I got started with Cypress

https://www.classdojo.com/

How I got started with Cypress

Starting Context:

  • Existing system already built and in production
  • We needed to refactor some application areas
  • The existing end-to-end tests were hard to write and not popular with dev teams
  • Mostly manual verification of changes

 

How I got started with Cypress

Part of ClassDojo DevEx team effort to:

  • make code base more uniform around current code patterns
  • make on-boarding of new developers to code base easier
  • increase build and deployment pipeline automation
  • make it easier to write end-to-end tests
  • increase test confidence

How I got started with Cypress

Cypress seemed to be the quickest and easiest way to provide a reliable safety net to enable refactoring, without being too tied to internal implementation and structure.

 

First steps

  • We had a few mob sessions with 6 people
  • 2 of which were already familiar with Cypress
  • within 2 weeks, all were confortable writting tests with Cypress

Biggest initial issues

  • Occasional false positive test failures
  • Test running time
  • Iframe file upload testing
  • Racing conditions reloading data

How we fixed them

  • Statistical analysis of failures
    • most of failures were related to assertions timing
    • debounced user interactions
    • variable network response
    • use network requests as stop points
  • Use Docker containers and docker-compose to run multiple instances of testing infrastructure in parallel

How it's been working so far

  • In the last 6 months, we've been doing heavy refactoring, with very little production disruption
  • We've expanded Cypress tests into 4 different web projects
  • Most flaky tests are not due to Cypress itself
  • Running 2 instances in parallel cut running time from 15 to 8 minutes (~140 test cases)
  • https://docs.cypress.io/

  • https://slides.com/bahmutov/flawless-tests#/

  • https://testdriven.io/blog/testing-angular-with-cypress-and-docker/

  • https://www.youtube.com/channel/UC-EOsTo2l2x39e4JmSaWNRQ

  • https://nx.dev/angular/guides/modernize-cypress

  • https://www.cypress.io/blog/2019/01/17/using-nrwl-nx-to-add-cypress-to-your-angular-development-workflow/

References

Using Cypress to build your E2E test suite

By Vitor Fernandes

Using Cypress to build your E2E test suite

  • 572