Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testing React Applications
Search
Max Stoiber
March 01, 2017
Technology
360
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Testing React Applications
Max Stoiber
March 01, 2017
More Decks by Max Stoiber
See All by Max Stoiber
Styling Intro
mxstbr
3
410
Introduction to React.js
mxstbr
1
170
Styling React Applications
mxstbr
2
730
Scaling React.js Applications (short version)
mxstbr
2
440
Scaling React.js Applications
mxstbr
0
440
Offline is the new Black
mxstbr
3
1.1k
Exploring ES6
mxstbr
1
340
Testing React.js Applications
mxstbr
4
750
Other Decks in Technology
See All in Technology
Claude Codeの体系的な理解と知識のフック
oikon48
10
6.5k
AI × Datadog MCP でコスト削減まで実現した Metric Streams の導入
three_mouth_ago
0
140
Nav2、Nav3 ... はたまた自作?〜 作って理解する Nav3 の設計意図 〜 / Nav2, Nav3 ... or Build Your Own? — Understanding Nav3's design intent by building it from scratch
yanzm
0
150
Claude Codeで開発以外の業務も爆速化しよう!
minorun365
PRO
12
9.5k
現場の暗黙知を継承するAIエージェント — 対話から生まれる長期記憶と Skills
atsukish
0
210
VPCでもFloatingIPを使いたいんだ
y_kotani
1
140
魔法少女がClaude Codeを監視する / ccportal-deck
noriyukitakei
3
110
本番に近いテストをもっと手軽に - Postmanで広がるAPIテストの世界 / Expanding the World of API Testing with Postman
yokawasa
1
220
サーバー常駐型の 簡易障害調査AI エージェントを作ってみた話
masayoshi
1
510
Bet AI Day 2026丨How We Bet AI: AIとともに働く場をつくる
layerx
PRO
1
1.6k
PM領域でのAI Agentの活用
lycorptech_jp
PRO
0
210
AI時代におけるプロダクト横断勉強会の設計
zozotech
PRO
0
110
Featured
See All Featured
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
800
The Invisible Side of Design
smashingmag
301
52k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
4.6k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
430
Measuring & Analyzing Core Web Vitals
bluesmoon
9
990
Discover your Explorer Soul
emna__ayadi
2
1.3k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
430
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
500
Crafting Experiences
bethany
1
270
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
370
Transcript
Let’s talk about testing
Which types of testing are there?
Unit Testing
Unit
Function Components Actions Reducers
Why should you test?
Catch some bugs before they happen
None
Executable Documentation
Write Better Code
// add.js export function add(x, y) { return x +
y; }
// add.test.js import { add } from './add.js'; describe('add()', ()
=> { it('adds two numbers', () => { expect(add(2, 3)).toEqual(5); }); it('doesnt add the third number', () => { expect(add(2, 3, 5)).toEqual(add(2, 3)); }); });
// add.test.js import { add } from './add.js'; describe('add()', ()
=> { it('adds two numbers', () => { expect(add(2, 3)).toEqual(5); }); it('doesnt add the third number', () => { expect(add(2, 3, 5)).toEqual(add(2, 3)); }); });
// add.test.js import { add } from './add.js'; describe('add()', ()
=> { it('adds two numbers', () => { expect(add(2, 3)).toEqual(5); }); it('doesnt add the third number', () => { expect(add(2, 3, 5)).toEqual(add(2, 3)); }); });
// add.test.js import { add } from './add.js'; describe('add()', ()
=> { it('adds two numbers', () => { expect(add(2, 3)).toEqual(5); }); it('doesnt add the third number', () => { expect(add(2, 3, 5)).toEqual(add(2, 3)); }); });
// add.test.js import { add } from './add.js'; describe('add()', ()
=> { it('adds two numbers', () => { expect(add(2, 3)).toEqual(5); }); it('doesnt add the third number', () => { expect(add(2, 3, 5)).toEqual(add(2, 3)); }); });
Max Stoiber – @mxstbr – mxstbr.com
// add.js export function add(x, y) { return x +
y; }
// add.js export function add(x, y) { return x +
y; x * y; }
None
Max Stoiber – @mxstbr – mxstbr.com
None
Redux
NavBar !"" NavBar.react.js # React component # !"" NavBar.actions.js #
Actions !"" NavBar.constants.js # Constants !"" NavBar.reducer.js # Reducer # !"" NavBar.actions.test.js # Actions tests $"" NavBar.reducer.test.js # Reducer tests
Actions
// NavBar.actions.js export function toggleNav() { return { type: "TOGGLE_NAV"
}; }
// NavBar.actions.test.js import { toggleNav } from './NavBar.actions'; describe('NavBar actions',
() => { });
describe('NavBar actions', () => { describe('toggleNav', () => { it('should
return the correct constant', () => { expect(toggleNav()).toEqual({ type: "TOGGLE_NAV" }); }); }); });
describe('NavBar actions', () => { describe('toggleNav', () => { it('should
return the correct constant', () => { expect(toggleNav()).toEqual({ type: "TOGGLE_NAV" }); }); }); }); export function toggleNav() { return { type: "TOGGLE_NAV" }; }
describe('NavBar actions', () => { describe('toggleNav', () => { it('should
return the correct constant', () => { expect(toggleNav()).toEqual({ type: "TOGGLE_NAV" }); }); }); });
None
Reducers
// NavBar.reducer.js const initialState = { open: false }; export
default function NavBarReducer(state = initialState, action) { switch (action.type) { case "TOGGLE_NAV": return { …state, open: !state.open }; default: return state; } }
// NavBar.reducer.js const initialState = { open: false }; export
default function NavBarReducer(state, action) { switch (action.type) { case "TOGGLE_NAV": return Object.assign({}, state, { open: !state.open }); default: return state; } }
describe('NavBarReducer', () => { it('returns the initial state', () =>
{ expect(NavBarReducer(undefined, {})).toEqual({ open: false }); }); it('handles the toggleNav action', () => { expect(NavBarReducer(undefined, toggleNav())).toEqual({ open: true }); }); });
describe('NavBarReducer', () => { it('returns the initial state', () =>
{ expect(NavBarReducer(undefined, {})).toEqual({ open: false }); }); it('handles the toggleNav action', () => { expect(NavBarReducer(undefined, toggleNav())).toEqual({ open: true }); }); });
describe('NavBarReducer', () => { it('returns the initial state', () =>
{ expect(NavBarReducer(undefined, {})).toEqual({ open: false }); }); it('handles the toggleNav action', () => { expect(NavBarReducer(undefined, toggleNav())).toEqual({ open: true }); }); });
describe('NavBarReducer', () => { it('returns the initial state', () =>
{ expect(NavBarReducer(undefined, {})).toEqual({ open: false }); }); it('handles the toggleNav action', () => { expect(NavBarReducer(undefined, toggleNav())).toEqual({ open: true }); }); });
None
Why Jest?
1. Performance 2. Snapshot Testing 3. Constant improvements
Components
const Button = (props) => ( <button className="btn" onClick={props.onClick} >
{props.children} </button> );
Jest Snapshot Testing
// Button.test.js import React from 'react'; import renderer from 'react-test-renderer';
import Button from './Button.react'; describe('<Button />', () => { it('should render a button with a classname', () => {}); it('should attach an onclick handler passed in', () => {}); it('should render its children', () => {}); });
// Button.test.js import React from 'react'; import renderer from 'react-test-renderer';
import Button from './Button.react'; describe('<Button />', () => { it('should render a button with a classname', () => {}); it('should attach an onclick handler passed in', () => {}); it('should render its children', () => {}); }); const Button = (props) => ( <button className="btn" onClick={props.onClick} > {props.children} </button> );
// Button.test.js describe('<Button />', () => { it('should render a
button with a classname', () => { const tree = renderer.create( <Button></Button> ).toJSON(); expect(tree).toMatchSnapshot(); }); it('should attach an onclick handler passed in', () => {}); it('should render its children', () => {}); });
// Button.test.js.snap exports[`<Button /> should render a button with a
classname 1`] = ` <button className="btn" onClick={undefined} /> `;
// Button.test.js describe('<Button />', () => { it('should render a
button with a classname', () => {}); it('should attach an onclick handler passed in', () => { const tree = renderer.create( <Button onClick={() => {}}></Button> ).toJSON(); expect(tree).toMatchSnapshot(); }); it('should render its children', () => {}); });
// Button.test.js describe('<Button />', () => { it('should render a
button with a classname', () => {}); it('should attach an onclick handler passed in', () => { const tree = renderer.create( <Button onClick={() => {}}></Button> ).toJSON(); expect(tree).toMatchSnapshot(); }); it('should render its children', () => {}); });
exports[`<Button /> should attach an onclick handler passed in 1`]
= ` <button className="btn" onClick={[Function]} /> `;
exports[`<Button /> should attach an onclick handler passed in 1`]
= ` <button className="btn" onClick={[Function]} /> `;
// Button.test.js describe('<Button />', () => { it('should render a
button with a classname', () => {}); it('should attach an onclick handler passed in', () => {}); it('should render its children', () => { const tree = renderer.create( <Button>Some text</Button> ).toJSON(); expect(tree).toMatchSnapshot(); }); });
// Button.test.js describe('<Button />', () => { it('should render a
button with a classname', () => {}); it('should attach an onclick handler passed in', () => {}); it('should render its children', () => { const tree = renderer.create( <Button>Some text</Button> ).toJSON(); expect(tree).toMatchSnapshot(); }); });
exports[`<Button /> should render its children 1`] = ` <button
className="btn" onClick={undefined}> Some text </button> `;
exports[`<Button /> should render its children 1`] = ` <button
className="btn" onClick={undefined}> Some text </button> `;
Quickest Testing Ever
Coverage
None
None
Let’s do some testing! git checkout 6-testing npm install npm
run test