Kent C. Dodds
Utah
wife, 4 kids, & a dog
PayPal, Inc.
if you are able ❤️ ♿️
if you are able
If you can, do it now, even if you've already done it...
git clone https://github.com/kentcdodds/testing-workshop.git
cd testing-workshop
npm run setup --silent
import React from 'react'
import ReactDOM from 'react-dom'
import ItemList from '../item-list'
test('renders "no items" when the item list is empty', () => {
const container = document.createElement('div')
ReactDOM.render(<ItemList items={[]} />, container)
expect(container.textContent).toMatch('no items')
})
test('renders the items in a list', () => {
const container = document.createElement('div')
ReactDOM.render(<ItemList items={['apple', 'orange', 'pear']} />, container)
expect(container.textContent).toMatch('apple')
expect(container.textContent).toMatch('orange')
expect(container.textContent).toMatch('pear')
})
import React from 'react'
import axiosMock from 'axios'
import {renderWithRouter, generate, Simulate} from 'til-client-test-utils'
import {init as initAPI} from '../utils/api'
import App from '../app'
beforeEach(() => {
window.localStorage.removeItem('token')
axiosMock.__mock.reset()
initAPI()
})
test('login as an existing user', async () => {
const {
getByTestId,
container,
getByText,
getByLabelText,
finishLoading,
} = renderWithRouter(<App />)
// wait for the app to finish loading the mocked requests
await finishLoading()
// navigate to login
const leftClick = {button: 0}
Simulate.click(getByText('Login'), leftClick)
expect(window.location.href).toContain('login')
// fill out form
const fakeUser = generate.loginForm()
const usernameNode = getByLabelText('Username')
const passwordNode = getByLabelText('Password')
const formWrapper = container.querySelector('form')
usernameNode.value = fakeUser.username
passwordNode.value = fakeUser.password
// submit form
const {post} = axiosMock.__mock.instance
const token = generate.token(fakeUser)
post.mockImplementationOnce(() =>
Promise.resolve({
data: {user: {...fakeUser, token}},
}),
)
Simulate.submit(formWrapper)
// wait for the mocked requests to finish
await finishLoading()
// assert calls
expect(axiosMock.__mock.instance.post).toHaveBeenCalledTimes(1)
expect(axiosMock.__mock.instance.post).toHaveBeenCalledWith(
'/auth/login',
fakeUser,
)
// assert the state of the world
expect(window.localStorage.getItem('token')).toBe(token)
expect(window.location.href).not.toContain('login')
expect(getByTestId('username-display').textContent).toEqual(fakeUser.username)
expect(getByText('Logout')).toBeTruthy()
})
import {assertRoute} from '../utils'
describe('authentication', () => {
it('should allow users to register', () => {
const user = {username: 'bob', password: 'wiley'}
cy
.visitApp()
.getByText('Register')
.click()
.getByLabelText('Username')
.type(user.username)
.getByLabelText('Password')
.type(user.password)
.getByText('Login')
.click()
cy.url().should('equal', 'http://localhost:3000/')
cy.getByTestId('username-display').should('contain', user.username)
})
})
¢heap
💰🤑💰
🏎💨
🐢
Simple problems 👌
Big problems 😖