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
350
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
誤解だらけの開発生産性 / Myths and Misconceptions about Developer Productivity
i35_267
2
790
CDKで書くECSのベストプラクティス、 改めて考え直す2026 #cdkconf2026
makies
3
770
Alphaモジュール使っていいのかい!?いけないのかい!?どっちなんだいっ!?
watany
1
270
AIレビューはどこまで任せられるのか?自動化と人が背負うレビューの境界
sansantech
PRO
3
1.1k
AIが実装を自走する時代の認知負債との戦い
lycorptech_jp
PRO
0
150
世界、断片、モデル。そして理解
ardbeg1958
1
130
最適な自走を最小限の支援で — M&Aで拡大する組織で少人数SREが挑んだ1年 / SRE NEXT 2026
genda
0
1.5k
Control Planeで育てるBtoB SaaSの認証基盤 - SRE NEXT 2026
pokohide
1
2.6k
壊して学ぶAWS CDK: そのcdk deployで消えるもの、残るもの
k_adachi_01
1
380
非定型なドキュメントを効率よくリファクタする 〜えぇ!?仕様書27本の移行が1日で終わったって!?〜
subroh0508
2
550
AI時代の闇と光
tatsuya1970
0
110
ボーイスカウトルールでメモリやスキルを改善しよう
azukiazusa1
4
1.4k
Featured
See All Featured
Accessibility Awareness
sabderemane
1
160
Paper Plane
katiecoart
PRO
2
52k
Music & Morning Musume
bryan
47
7.3k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Ruling the World: When Life Gets Gamed
codingconduct
0
280
How GitHub (no longer) Works
holman
316
150k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
470
Become a Pro
speakerdeck
PRO
31
6k
Automating Front-end Workflow
addyosmani
1370
210k
Between Models and Reality
mayunak
4
370
Java REST API Framework Comparison - PWX 2021
mraible
34
9.5k
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