Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing React Applications

Testing React Applications

48619fc17b3ab68472aebd56c0106278?s=128

Max Stoiber

March 01, 2017
Tweet

Transcript

  1. Let’s talk about testing

  2. Which types of testing are there?

  3. Unit Testing

  4. Unit

  5. Function Components Actions Reducers

  6. Why should you test?

  7. Catch some bugs before they happen

  8. None
  9. Executable Documentation

  10. Write Better Code

  11. // add.js export function add(x, y) { return x +

    y; }
  12. // 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)); }); });
  13. // 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)); }); });
  14. // 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)); }); });
  15. // 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)); }); });
  16. // 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)); }); });
  17. Max Stoiber – @mxstbr – mxstbr.com

  18. // add.js export function add(x, y) { return x +

    y; }
  19. // add.js export function add(x, y) { return x +

    y; x * y; }
  20. None
  21. Max Stoiber – @mxstbr – mxstbr.com

  22. None
  23. Redux

  24. 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
  25. Actions

  26. // NavBar.actions.js export function toggleNav() { return { type: "TOGGLE_NAV"

    }; }
  27. // NavBar.actions.test.js import { toggleNav } from './NavBar.actions'; describe('NavBar actions',

    () => { });
  28. describe('NavBar actions', () => { describe('toggleNav', () => { it('should

    return the correct constant', () => { expect(toggleNav()).toEqual({ type: "TOGGLE_NAV" }); }); }); });
  29. describe('NavBar actions', () => { describe('toggleNav', () => { it('should

    return the correct constant', () => { expect(toggleNav()).toEqual({ type: "TOGGLE_NAV" }); }); }); }); export function toggleNav() { return { type: "TOGGLE_NAV" }; }
  30. describe('NavBar actions', () => { describe('toggleNav', () => { it('should

    return the correct constant', () => { expect(toggleNav()).toEqual({ type: "TOGGLE_NAV" }); }); }); });
  31. None
  32. Reducers

  33. // 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; } }
  34. // 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; } }
  35. 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 }); }); });
  36. 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 }); }); });
  37. 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 }); }); });
  38. 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 }); }); });
  39. None
  40. Why Jest?

  41. 1. Performance 2. Snapshot Testing 3. Constant improvements

  42. Components

  43. const Button = (props) => ( <button className="btn" onClick={props.onClick} >

    {props.children} </button> );
  44. Jest Snapshot Testing

  45. // 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', () => {}); });
  46. // 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> );
  47. // 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', () => {}); });
  48. // Button.test.js.snap exports[`<Button /> should render a button with a

    classname 1`] = ` <button className="btn" onClick={undefined} /> `;
  49. // 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', () => {}); });
  50. // 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', () => {}); });
  51. exports[`<Button /> should attach an onclick handler passed in 1`]

    = ` <button className="btn" onClick={[Function]} /> `;
  52. exports[`<Button /> should attach an onclick handler passed in 1`]

    = ` <button className="btn" onClick={[Function]} /> `;
  53. // 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(); }); });
  54. // 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(); }); });
  55. exports[`<Button /> should render its children 1`] = ` <button

    className="btn" onClick={undefined}> Some text </button> `;
  56. exports[`<Button /> should render its children 1`] = ` <button

    className="btn" onClick={undefined}> Some text </button> `;
  57. Quickest Testing Ever

  58. Coverage

  59. None
  60. None
  61. Let’s do some testing! git checkout 6-testing npm install npm

    run test