Testing Practices and Principles
Kent C. Dodds
Utah
wife, 4 kids, & a dog
PayPal, Inc.
Please Stand...
if you are able ❤️ ♿️
What this talk is
-
Fundamentals behind tests and testing frameworks
-
Distinctions of different forms of testing
-
Writing unit and integration
-
Test doubles (mocks/stubs/etc.)
-
Use TDD to write new features and to find and fix bugs
-
Core principles of testing to ensure your tests give you the confidence you need
What this talk is not
- Technology-specific
- How to configure tools
- Free of trade-offs
- Long presentation
- Covering all forms of testing
Setup
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
Logistics
- 🙋 Raise your hand to ask and answer questions. Feel free to make relevant comments as well!
- 💬 🌎 Use the workshop chat room (gitter.im/kentcdodds/testing-workshop) to ask and answer each others questions.
- 💬 😀 Chat with me one-on-one (gitter.im/kentcdodds). I'll try to respond during exercises.
- 📑 Fill out the elaboration and feedback forms for every exercise.
- 📧 Ask questions on my AMA (kcd.im/ama).
- 🐦 Follow me on twitter 😉 (twitter.com/kentcdodds).
Routine
- Demos 👨💻
- Exercises 💪 (pair programming!?)
- Elaboration and Feedback Form 📑
- ? Bonus 👨🎓 👩🎓
- ? Help others 👩🔬 👨🔬
- ? Make pull requests 🙏
Let's
Get
STARTED!
What kind of bugs are there?
Business Logic 🕷
Security 🕷
Accessibility 🐜
User Interface 🐞
Performance 🐛
Regression 🐞
Internationalization 🕷
Integration 🐜
Scaling 🐛
How do we prevent bugs?
- Static Types: Flow / TypeScript
- Linting: ESLint
- Testing: ??
What kinds of testing can we do?
Unit Testing
Regression Testing
Integration Testing
E2E Testing
Smoke Testing
Usability Testing
i18n Testing
Penetration Testing
User Acceptance Testing
Performance Testing
A/B Testing
a11y Testing
Stress Testing
Fuzz Testing
Static Code Analysis
Unit tests
function sum(a, b) {
return a + b
}
test('sum adds numbers', () => {
expect(sum(1, 3)).toBe(4)
})
Integration tests
let api, server
beforeAll(async () => {
server = await startServer()
const {port} = server.address()
api = axios.create({
baseURL: `http://localhost:${port}/api`
})
})
afterAll(() => server.close())
beforeEach(() => resetDb())
test('can register a user', async () => {
const registerData = {username: 'bob', password: 'wiley'}
const testUser = await api
.post('auth/register', registerData)
.then(response => response.data.user)
expect(testUser.username).toBe(registerData.username)
const readUserUnauthenticated = await api
.get(`users/${testUser.id}`)
.then(response => response.data.user)
expect(readUserUnauthenticated).toEqual(testUser)
})
End-to-end tests
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)
})
})
🚗 Test Driven Development 🏎
Red
Green
Refactor
🐛 Fixing Bugs 🐜
Bug
Find Code
Write Test
Fix Test
The Testing Trophy
¢heap
💰🤑💰
🏎💨
🐢
Simple problems 👌
Big problems 😖
Resources
My blog/newsletter has a lot of content about testing too: blog.kentcdodds.com
Thank you!
Testing Practices and Principles
By Kent C. Dodds
Testing Practices and Principles
The goal of a test is to increase your confidence that the subject of your test is functioning the way it should be. Not all tests provide the same level of confidence (some provide very little confidence at all). If you’re not doing things correctly, you could be wasting your time and giving yourself a false sense of security (even worse than having no tests at all).
- 10,431