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
400
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
740
Other Decks in Technology
See All in Technology
サイバー捜査員研修(前半)
nomizone
1
2k
Forza Horizon 6 のテレメトリ機能で 自動運転に使えそうな学習データを集める話
henjin0
0
170
制約理論(ToC)入門 2026版
recruitengineers
PRO
8
2.3k
メルカリのグローバルアプリで挑んだ AlloyDB 運用と課題解決の実践記
hatappi
0
250
MulticaとPi Coding Agentで、小規模OSSを30本同時運用した流れ
eiei114
0
100
【CEDEC2026】コードレビュー支援ツール開発から学ぶ:LLMを用いた業務システムの実践的な運用設計と誤出力対策
cygames
PRO
0
750
Webアクセシビリティ入門 2026
recruitengineers
PRO
3
560
ラジオの科学
frievea
0
310
Breaking the Seal: Static Deobfuscation of Compiled V8 JavaScript Bytecode Malware
hshrzd
0
750
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
4
24k
第3回しろおびセキュリティスポンサーセッション
log0417
0
180
Bits Agent Builder の⼊⾨と活⽤事例
nulabinc
PRO
0
140
Featured
See All Featured
New Earth Scene 8
popppiees
3
2.5k
A Tale of Four Properties
chriscoyier
163
24k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
300
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
380
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
280
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
GitHub's CSS Performance
jonrohan
1033
470k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
660
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.7k
Six Lessons from altMBA
skipperchong
29
4.4k
Embracing the Ebb and Flow
colly
88
5.1k
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