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