Gleb Bahmutov PRO
JavaScript ninja, image processing expert, software quality fanatic
ReactJS Boston
C / C++ / C# / Java / CoffeeScript / JavaScript / Node / Angular / Vue / Cycle.js / functional
EveryScape
virtual tours
MathWorks
MatLab on the web
Kensho
finance dashboards
8 people. Atlanta, Philly, Boston, LA
Fast, easy and reliable testing for anything that runs in a browser
E2E
integration
unit
E2E
integration
unit
(enzyme with full rendering)
E2E
integration
unit
You go to a dealership to take a new car for a test drive, not to measure its wheels
planning
coding
deploying
staging / QA
production
E2E
E2E
Users
planning
coding
deploying
staging / QA
production
💵
E2E
E2E
Users
💵
🐞$0
💵
💵
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💵
💵
planning
coding
deploying
staging / QA
production
💵
E2E
E2E
Users
💵
🐞$0
💵
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
💰
Answer: E2E
💵
💵
💵
Your tests
Selenium
Driver
FF, Chrome , IE
Your tests
FF, Chrome , IE
slow, flaky, unreliable tests
Your tests
FF, Chrome , IE
Your tests
Headless browser
What is happening?
$ npm install -D cypress
// ui-spec.js
it('loads the app', () => {
cy.visit('https://some-url.com')
cy.get('.todoapp').should('be.visible')
})
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)
})
})
})
E2E
integration
unit
E2E
integration
unit
WAIT A MINUTE!
$ npm install -D cypress cypress-react-unit-test
import { HelloSpider } from './src/hello-spiderman.jsx'
import React from 'react'
import { mount } from 'cypress-react-unit-test'
React component test demo with Cypress
it('works', () => {
mount(<HelloSpider />)
// start testing!
cy.contains('Hello Spider-man!')
})
E2E
integration
unit
Why are they called
cypress-<X>-unit-test ?!
E2E
integration
unit
function add(a, b) {
return a + b
}
add(a, b)
outputs
inputs
a, b
returned value
it('adds', () => {
expect(add(2,3)).to.equal(5)
})
function add(a, b) {
const el = document.getElementById('result')
el.innerText = a + b
}
add(a, b)
outputs
inputs
a, b
DOM
it('adds', () => {
add(2,3)
const el = document.getElementById('result')
expect(el.innerText).to.equal('5')
})
function add() {
const {a, b} =
JSON.parse(localStorage.getItem('inputs'))
const el = document.getElementById('result')
el.innerText = a + b
}
add(a, b)
outputs
inputs
localStorage
DOM
it('adds', () => {
localStorage.setItem('inputs') =
JSON.stringify({a: 2, b: 3})
add()
const el = document.getElementById('result')
expect(el.innerText).to.equal('5')
})
component
outputs
inputs
DOM,
localStorage,
location,
HTTP,
cookies
WW, SW,
...
DOM,
localStorage,
location,
HTTP,
cookies
WW, SW,
...
component
outputs
inputs
DOM,
localStorage,
location,
HTTP,
cookies
WW, SW,
...
DOM,
localStorage,
location,
HTTP,
cookies
WW, SW,
...
Set up
Assert
Mount
E2E
unit
it('logs user in', () => {
cy.visit('page.com')
cy.get('#login').click()
})
E2E
unit
it('logs user in', () => {
mount(LoginComponent)
cy.get('#login').click()
})
E2E
unit
Use same syntax, life cycle and Cypress API
🔋🔋🔋🔋🔋🔋🔋🔋🔋🔋🔋
@cypress_io
@bahmutov
By Gleb Bahmutov
Testing is hard. End to end testing is really hard. But maybe it is hard because our tools are not up to task. What if we could redesign the testing experience from the ground up to be fast, useful and effective? Let me show you how to quickly test a React application using Cypress.io - an open source modern test runner that replaces Selenium. Don't believe the hype - come see Cypress demo for yourself, and I guarantee you will start writing tests. Presented at ReactJS Boston meetup April 2018. Video at https://www.youtube.com/watch?v=lgurVvQsOTY
JavaScript ninja, image processing expert, software quality fanatic