Gleb Bahmutov, PhD

VP of Engineering, Cypress.io

Cypress: testing without Selenium

Part 1

C / C++ / C# / Java / CoffeeScript / JavaScript / Node / Angular / Vue / Cycle.js / functional / testing

πŸ–₯ πŸ‡¬πŸ‡§

πŸ—£ πŸ‡·πŸ‡Ί

❀️ πŸ‡ΊπŸ‡¦

18 people. Atlanta, Philly, Boston, Chicago, NYC

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

I have Cypress.io stickers

Why is all software broken?

Will Klein

Contents: Part 1

  • Testing pyramid

  • Testing in real browser

  • Cypress demo

Contents: Part 2

  • Cypress architecture

  • Declarative test syntax

  • Code coverage updates

  • CircleCI Orbs

  • Component and API testing

Quality software behaves the way users expect it to behave

We going to need some tests

E2E

integration

unit

Smallest pieces

Testing Pyramid β–³

Unit tests pass...

E2E

integration

unit

Component

E2E

integration

unit

Website / API

E2E

integration

unit

Really important to users

Really important to developers

E2E

integration

unit

Web application

  • Open real browser
  • Load actual app
  • Interact with app like a real user
  • See if it works

Let's test!

  1. Open and control real browser

Your tests

Selenium

Driver

FF, Chrome , IE

Let's test!

  1. Open and control real browser

Your tests

Selenium

Driver

FF, Chrome , IE

βœ… JavaScript, Java, Python, C#, etc

Let's test!

  1. Open and control real browser

Your tests

Selenium

Driver

FF, Chrome , IE

⚠️ HTTP request

Let's test!

  1. Open and control real browser

Your tests

FF, Chrome , IE

slow, flaky, unreliable tests

Let's test!

Your tests

Headless browser

What is happening?

Cypress vs X

People testing with Selenium / WebDriver

Cypress users?

No E2E tests

E2E should be easy

  • Easy to install

  • Easy to write tests

  • Simple to run

Easy to debug when a test fails

Cypress.io

Electron based cross-platform app

Let's test!

Your tests

Your web app

Cypress App

start

Chrome (for now)

Cypress.io: recommended

Cypress.io: recommended

Learn Node

JavaScript around us

  • Browser

  • Server

  • Desktop

  • Mobile

  • Gray areas:

    • IoT, robots, code snippets, build scripts, sw

JavaScript around us

  • Browser

  • Server

  • Desktop

  • Mobile

  • Gray areas:

    • IoT, robots, code snippets, build scripts, sw

only runs JavaScript

With Node you get NPM

Install Node tools and 3rd party dependencies

# start new Node project
npm init
# add Cypress dependency
npm install --save-dev cypress
# open Cypress
npx cypress open

Cypress.io: recommended

Cross-platform JavaScript environment

another useful tool included in Node

$ npm install -D cypress
npx cypress open

Created folders:

  • integration - with tests
  • support - custom commands
  • plugins - ways to customize Cypress
  • fixtures - JSON mock data

cypress.json - customize Cypress settings

For power users

npx @bahmutov/cly init
// ui-spec.js
it('loads the app', () => {
  cy.visit('http://localhost:3030')
  cy.get('.todoapp').should('be.visible')
})

Mocha BDD syntax

Chai assertions

it('adds 2 todos', () => {
  cy.visit('http://localhost:3000')
  cy.get('.new-todo')
    .type('learn testing{enter}')
    .type('be cool{enter}')
  cy.get('.todo-list li')
    .should('have.length', 2)
})

fluent API like jQuery

it('adds 2 todos', () => {
  cy.visit('http://localhost:3000')
  cy.get('.new-todo')
    .type('learn testing{enter}')
    .type('be cool{enter}')
  cy.get('.todo-list li')
    .should('have.length', 2)
})

assertions

commands

import {resetDatabase} from '../utils'
const visit = () => cy.visit('/')

describe('UI', () => {
  beforeEach(resetDatabase)
  beforeEach(visit)

  context('basic features', () => {
    it('starts with zero items', () => {
      cy.get('.todo-list')
        .find('li')
        .should('have.length', 0)
    })
  })
})

bundling included

base url in cypress.json

cy.request, cy.task, cy.exec

1 * πŸ‘€ Β > 100 * πŸ‘‚

Cypress demo

  • Typical test
    • point at any server
  • Intelligent code completion
  • Commands and assertions
  • Failing test
  • Videos and screenshots

Cypress demo

  • Custom commands
  • Network control
  • Application access
  • CI setup
  • Cypress dashboard

Cypress Types

types/
  index.d.ts

package.json
  "types": "types"

Explains global "cy" object

User test - just add this comment

Explains "cy.visit" command

Completion for BDD assertions

Completion for specific assertion with examples

IntelliSense-driven development

every command and assertion

links to full docs

inline examples

  1. read docs for hours
  2. go through the tutorial*
  3. read more docs
  4. write tests

New Testing Tool

  1. read "Hello World"
  2. copy to your test
  3. write useful tests
  4. gradually improve

New Testing Tool

Our goal: no matter how well you know JavaScript = you are successfully using Cypress

Giant API

80 commands + events + utilities (lodash, moment, jQuery) + assertions

Every command

  • Syntax
  • Correct usage
  • Incorrect usage
  • Options
  • What it logs
  • Examples and best practices

Tutorials

Api

Examples

Video course

Full workshop

Bonus: JSON IntelliSense

VSCode: in the user settings, global or workspace set:

{
  "json.schemas": [
    {
      "fileMatch": ["cypress.json"],
      "url": "https://on.cypress.io/cypress.schema.json"
    }
  ]
}

VSCode alternative: add "$schema" property to your JSON file

{
  "viewportWidth": 600,
  "viewportHeight": 800,
  "ignoreTestFiles": "answer.js",
  "baseUrl": "http://localhost:3000",
  "$schema": "https://on.cypress.io/cypress.schema.json"
}

Commands and Assertions

BDD / TDD assertions

http://on.cypress.io/assertions

it('adds items', function () {
  cy.get('.new-todo')
    .type('todo A{enter}')
    .type('todo B{enter}')
    .type('todo C{enter}')
    .type('todo D{enter}')
  cy.get('.todo-list li').should('have.length', 2)
})

Command + assertion

command

assertion

it('adds items', function () {
  cy.get('.new-todo')
    .type('todo A{enter}')
    .type('todo B{enter}')
    .type('todo C{enter}')
    .type('todo D{enter}')
  cy.get('.todo-list li', {timeout: 1000000})
    .should('have.length', 2)
})

Retry longer

helping live web application during the test

Test Failed πŸŽ‰

Tests are useful when they fail

Test Failed πŸŽ‰

Look at the screenshot

Test Failed πŸŽ‰

Watch the video

Cypress demo

  • Typical test
    • point at any server
  • Intelligent code completion
  • Commands and assertions
  • Failing test
  • Videos and screenshots

Cypress demo

  • Custom commands
  • Network control
  • Application access
  • CI setup
  • Cypress dashboard

Why developers love Cypress

  • Fast, flake-free

  • GUI, time travel

  • Test recording

  • Documentation

Why developers love Cypress

  • Fast, flake-free

  • GUI, time travel

  • Test recording

  • Documentation

100% FREE & OSS

Where Cypress.io is not there yet

  • Multiple domains

  • Only JavaScript

  • Iframes

End of Part 1

stay for Part 2