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
[DroidKaigi 2026] Making UI specifications visible: Android UI development in the AI agent era supported by Compose Screenshot Testing and galleries
syarihu
0
570
Kiro Crewしか勝たん!?
miu_crescent
PRO
0
180
生成AI時代の クレデンシャルとパーミッション設計
nrinetcom
PRO
3
1.5k
どんな手を使っても絶対間に合わせるスケジューラ
asari194617
0
1.6k
Azure App Service / Container Apps の組み込み認証
kuniteru
0
190
KPIだけでは評価できないプロダクトが考えるべき Evalsという第二の評価系 / Beyond KPIs: Evals as a Second Evaluation Framework for Products #PdEConf
aki_iinuma
4
3.6k
Guerilla InnerSource in enterprises, during the AI hype
onenashev
PRO
0
150
AIとペアプロを始める。人とのペアプロをやめる。ペアプロの良さを改めて知る。もっと好きになった。 / Rediscovering Pair Programming
honyanya
1
230
AIエージェントを雇う前に決める5つのこと
knishioka
1
160
いま、生成AIにKaggleをどこまで 任せられるか — ROGIIコンペでの進め方とTips
k951286
3
1.4k
少人数データチームのDevin活用実践事例
runandy16
2
440
When Does a Local Qwen Start to Break
morshoto
0
170
Featured
See All Featured
Discover your Explorer Soul
emna__ayadi
2
1.3k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
660
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
450
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Google's AI Overviews - The New Search
badams
0
1.6k
Believing is Seeing
oripsolob
1
210
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
570
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
460
Optimizing for Happiness
mojombo
378
71k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
520
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