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

使用 Jest 進行 Front-End Unit Test

Patrick Wang
September 26, 2016

使用 Jest 進行 Front-End Unit Test

* Frameworks
* Jest 基本設定
* Enzyme
* 語法與規則
* 各部分 Test 重點與方法
* 其他小技巧
* Coverage

文章:https://blog.patw.me/archives/1310/write-frontend-unit-tests-with-jest/

Patrick Wang

September 26, 2016
Tweet

More Decks by Patrick Wang

Other Decks in Programming

Transcript

  1. ֵአ Jest 蝱ᤈ Front-End Unit Test
    Patrick Wang (patw)
    2016/09/26

    View Slide

  2. य़姛

    View Slide

  3. • Frameworks
    • Jest च๜戔ਧ
    • Enzyme
    • 承ဩ膏憒㳷
    • ݱ蟂獤 Test ᯿讨膏ොဩ
    • ٌ犢ੜದૣ
    • Coverage

    View Slide

  4. Frameworks

    View Slide

  5. Frameworks
    • Unit Test
    • Jasmine
    • Mocha, Chai, Sinon
    • Jest
    • AVA

    View Slide

  6. Assertion Libraries
    http://reactmad-testing.surge.sh/#/4

    View Slide

  7. Frameworks
    • E2E Test
    • Casper.js
    • Protractor
    • Nightwatch.js
    • CodeceptJS
    http://reactmad-testing.surge.sh/#/5

    View Slide

  8. Jest च๜戔ਧ

    View Slide

  9. ਞ蕕 & 戔ਧ
    jest & enable babel
    .babelrc

    View Slide

  10. npm scripts
    package.json
    瞱媲緳፡
    叨ኞ coverage 奾ຎ
    ᪒介手

    View Slide

  11. jest configuration
    package.json
    import ᪠䕩
    ࣁ᪒介手ԏ獮ጱ絑ह伛猋戔ਧ
    懯獈 coverage ጱፓ袅
    stub scss 䲆礯
    介手脻๜ጱ䲆ݷ pattern

    View Slide

  12. jest configuration
    jest/setupTests.js
    蝡螲ฎ傶ԧ mock ധ localStorage

    View Slide

  13. jest configuration
    jest/styleStub.js
    If you want to test classname (CSS Modules)…
    e.g., styles.foobar === 'foobar'
    Notice that Proxy is enabled in Node.js v6.* by default; if you are not on Node v6.* yet, make sure
    you invoke Jest using node --harmony_proxies node_modules/.bin/jest.

    View Slide

  14. Enzyme

    View Slide

  15. Enzyme
    • by Airbnb
    • ੗蕕ԧ React ጱਥො介手ૡٍ牧䢐磪觊犲 jQuery ጱ
    螡䢔瑊 API牧介手砰䌃Ӥๅො׎

    View Slide

  16. Enzyme - find
    • ֵአ React TestUtils 螡玲粬ਧፓ秂ጱ API物

    TestUtils.findRenderedDOMComponentWithXXXX
    • ֵአ Enzyme ݝᥝ component.find(selector) ܨݢ物

    View Slide

  17. Enzyme
    • shallow
    • render
    • mount

    View Slide

  18. Enzyme - shallow
    • ੗蕕ਥොጱ shallow rendering
    • ݝ჉礕ᒫӞ䍅牧犋჉礕ৼزկ
    • 蝧ଶ盠
    • 犋ᓕ child component ጱᤈ傶牧介手᯿讨ݝฎ
    component ๜蛪

    View Slide

  19. Enzyme - render
    • 觊犲 shallow牧ֵ֕አ Cheerio ୚砻
    • 犋ݝ჉礕Ӟ䍅
    • API 蚤 shallow च๜ӤӞ膌

    View Slide

  20. Enzyme - mount
    • Full rendering
    • ፥䋿ጱ DOM ℄讨
    • మᥝ介手膏 DOM ጱ԰㵕膏盅媲叨ኞጱ虋玕ҁই
    Click 盅㳫ᴻԧӞ㮆 list ጱ殻ፓ҂
    • మᥝ介手ਠ碉ጱኞ޸蝰๗

    View Slide

  21. 承ဩ膏憒㳷

    View Slide

  22. describe & it
    介手脻๜愊ᶎ䛑扗۱ೡӞ㮆౲ग़㮆describe璸牧ྯ㮆describe璸䛑
    扗۱ೡӞ㮆౲ग़㮆it璸牐
    describe璸圸傶"介手ॺկ"ҁtest suite҂牧蔭纈Ӟ奲ፘ橕ጱ介手牐
    ਙฎӞ㮆獢碍牧ᒫӞ㮆㷢碍ฎ介手ॺկጱݷ圸ҁ"ےဩ獢碍ጱ介手
    "҂牧ᒫԫ㮆㷢碍ฎӞ㮆䋿褬䁆ᤈጱ獢碍牐
    it璸圸傶"介手አֺ"ҁtest case҂牧蔭纈Ӟ㮆㻌加ጱ介手牧ฎ介手ጱ
    磧ੜ㻌֖牐ਙ犖ฎӞ㮆獢碍牧ᒫӞ㮆㷢碍ฎ介手አֺጱݷ圸ҁ"1 ے
    1 䛑扗缛ෝ 2"҂牧ᒫԫ㮆㷢碍ฎӞ㮆䋿褬䁆ᤈጱ獢碍牐
    http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

    View Slide

  23. describe & it
    http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html
    import add from './add';
    import { expect } from 'chai';
    describe('ےဩ獢碍ጱ介手', function () {
    it('1 ے 1 䛑扗缛ෝ 2', function () {
    expect(add(1, 1)).to.be.equal(2);
    });
    });

    View Slide

  24. expect
    ಅ蘎"䥁᥺"牧疰ฎڣ䥁რ嘨ጱ䋿褬䁆ᤈ奾ຎ膏毆๗奾ຎ
    ฎ玽Ӟ膌牧ইຎ犋Ӟ膌疰瞦ڊӞ㮆梊藮牐
    http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html
    expect(add(1, 1)).to.be.equal(2);

    View Slide

  25. Jest ൉׀ጱ API
    • describe, it
    • xdescribe, xit - 䧙碻᪡螂介手碻ֵአ
    • fit - 㰍᪒種ྦྷ介手
    • beforeEach - ࣁྯ㮆介手ԏ獮᮷䁆ᤈ
    • afterEach - ࣁྯ㮆介手ԏ盅᮷䁆ᤈ
    http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

    View Slide

  26. Jest ൉׀ጱ API
    • expect
    • .toBe(value)
    • .not
    • .toBeTruthy(), .toBeFalsy()
    • .toEqual(value)
    • .toBeCalled()
    • .toBeCalledWith(arg1, arg2, …)
    http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

    View Slide

  27. 䌕礯ֵአጱ介手䲆礯޸ݷ憒㳷 (1/2)
    • ཿ介手ጱ source ݶ䍅樄Ӟ㮆 __tests__ ፓ袅
    • 䲆ݷ物{source 䲆ݷ}.test.js
    • ݚक़牧ࢩፓ獮ֵአ Ducks: Redux Reducer Bundles ጱ憒塅砰
    䌃 redux牧硲 reducers 膏 actions ጱ޸ݷ憒塅ইӥ物
    • Actions: {source 䲆ݷ}.actions.test.js
    • Reducers: {source 䲆ݷ}.reducers.test.js

    View Slide

  28. 䌕礯ֵአጱ介手䲆礯޸ݷ憒㳷 (2/2)
    • 舙襑ਧ嬝盄裾ጱ fake data牧ୌ捍ݚक़ୌӞඪ䲆礯硯ᗝ牧㪔
    硯ᗝࣁݶӞ䍅牐ٚෝ介手䲆礯Ӿ import 蝱㬵ֵአ牐
    • 犥 reselect ጱ newsByCat 傶ֺ牧׎ୌ缏ԧ物
    • newsByCat-newsByIdItemData.js物

    newsById 奾䯤ጱ؃虻碘
    • newsByCat-makeState.js物

    蜍獈 newsByCat-newsByIdItemData.js ጱ؃虻碘盅牧叨
    ڊӞ犩؃ state ׀扗 reselect 介手ֵአ

    View Slide

  29. ݱ蟂獤 Test ᯿讨膏ොဩ

    View Slide

  30. Component
    介手᯿讨
    1. Snapshot 介手 (Jest v14.0 ڊ匍)
    • 穉䌘叨ኞ HTML ጱ奾ຎฎ玽膏Ӥ稞盠ᆙፘᒧ
    • 犖磪Ոአࣁ reducer
    • https://facebook.github.io/jest/blog/2016/07/27/jest-14.html/
    2. Simulate ᤈ傶介手
    ࢩ種盠ᆙ犖ᥝ蝱 git

    View Slide

  31. Component - snapshot
    snapshot

    View Slide

  32. Component - simulate (with mount)

    View Slide

  33. Container
    介手᯿讨
    1. Container 膏ٌ Component ᮷磪ᤩ render ڊ㬵
    • 襑አ ۱蚏㬵
    2. ᤩ Mock ጱ Component 磪ᤩ call Ӟ稞

    View Slide

  34. Container
    伛猋؃虻碘牏አ Provider ۱蚏㬵牏㯽獈 context

    View Slide

  35. Container
    ᛔ૩ mock createStore

    View Slide

  36. Container
    Component 磪ᤩ call Ӟ稞
    磪 render 奾ຎ

    View Slide

  37. Reducer
    介手᯿讨
    1. 蜍獈 initial state 膏 action 盅牧蜴ࢧ毆๗ጱ state
    2. 蝫媲蜍獈 state 膏 action 盅牧膏 snapshots ፘᒧ

    View Slide

  38. Reducer

    View Slide

  39. Reducer - Snapshot test
    https://twitter.com/villeimmonen/status/772754403187126272

    View Slide

  40. snapshot አෝ reducer
    snapshot

    View Slide

  41. Action
    介手᯿讨
    1. 䁆ᤈ action 盅牧蜴ࢧ毆๗ጱ object (type 膏
    payloads)
    2. 瞚Ӥ牧֕Ӿ樌妿螂 mock 螂ጱ ajax

    View Slide

  42. Action

    View Slide

  43. Action - mock ajax (1/4)
    • nock
    • mock the HTTP requests

    • redux-mock-store
    • apply the middleware to a mock store
    http://redux.js.org/docs/recipes/WritingTests.html#async-action-creators

    View Slide

  44. Action - mock ajax (2/4)

    View Slide

  45. Action - mock ajax (3/4)

    View Slide

  46. Action - mock ajax (4/4)
    ಩ܻ๜ ajax ጱ蟂犩 mock ധ
    犖ݢ犥አ ES7 await/async

    View Slide

  47. Reselect
    介手᯿讨
    1. 懯ᓒ奾ຎ膏毆๗ፘᒧ
    2. 蜍獈ፘݶጱ独牧犋䨝᯿碝懯ᓒ (recomputations)

    View Slide

  48. Reselect
    ࣁ beforeEach Ӿ懿஑ jest.resetModules()

    View Slide

  49. Router (1/4)
    介手᯿讨
    1. params / path ፘᒧ
    2. property ፘᒧҁই物䢐磪 hideTopAd҂
    3. Component ፘᒧ

    View Slide

  50. Router (2/4)

    View Slide

  51. Router (3/4)

    View Slide

  52. Router (4/4)

    View Slide

  53. ٌ犢ੜದૣ

    View Slide

  54. jest.mock(module_path, fn) (1/2)
    • Jest 粬ᜋԏӞ牧虏介手䌕ဳࣁ匍ࣁ介手ጱ秇奲๜蛪牧
    import ጱ module mock ധ牧螨ع୽段介手Ӿጱ秇
    奲牐
    • ֕ Jest v15 蚏牧automocking 毆戔ฎ橕ധጱ牐ҁਥ
    ො藯ก҂

    View Slide

  55. jest.mock(module_path, fn) (2/2)

    View Slide

  56. jest.resetModules()
    嘦狒 import/require ጱ module ䷱磪ᤩ࿱礕牐
    蝢ଉ硯ࣁ beforeEach() Ӿ物

    View Slide

  57. jest.fn() (1/2)
    ಩ᒫӣො౲㯽獈ጱ function mock 蚏㬵牧ই種㰍ᥝ介手
    ᤩ call ጱ稞碍౲ฎᴫ癲㯽獈ጱ㷢碍ฎ玽ྋ嘦ܨݢ牐
    ֺ物ࣁ纷ୗ嘨Ӿ޷ݞԧ ga/piwik ጱ纷ୗ嘨牧֕介手碻䷱磪஠ᥝ

    斉獈 ga牧ݝᥝ jest.fn() mock 蚏㬵疰অ牐

    View Slide

  58. jest.fn() (2/2)
    介手ݢ犥介扗 mock 螂ጱ function ฎ玽ᤩ call牫

    ᤩ call ጱ碻狡ᴫ癲Ջ讕㷢碍牫
    ࣁ beforeEach Ӿአ mockFn.mockClear() 嘦狒ྯ稞᮷
    ᯿ᗝ制眲ҁ㯽獈㷢碍牏稞碍҂牐

    View Slide

  59. timer ፘ橕 mock (1/3)
    朼䌘 timer 犖ݢ犥 mock牧jest.useFakeTimers()
    Instructs Jest to use fake versions of the standard
    timer functions (setTimeout, setInterval, clearTimeout,
    clearInterval, nextTick, setImmediate and
    clearImmediate).
    https://facebook.github.io/jest/docs/timer-mocks.html#content

    View Slide

  60. timer ፘ橕 mock (2/3)
    https://facebook.github.io/jest/docs/timer-mocks.html#content

    View Slide

  61. timer ፘ橕 mock (3/3)
    https://facebook.github.io/jest/docs/timer-mocks.html#content

    View Slide

  62. Async Test
    Async/Await
    Error Handling
    https://facebook.github.io/jest/docs/tutorial-async.html#content

    View Slide

  63. Coverage

    View Slide

  64. Coverage
    jest 獉ୌ coverage牐౯㮉犖ࣁ package.json 戔ਧঅ script ԧ牐
    䨝礬硁 package.json Ӿ jest.collectCoverageFrom 戔ਧጱፓ袅塅瑻懯ᓒ coverage牐

    叨ኞ蝡䰬ጱ奾ຎ物

    View Slide

  65. Coverage
    犖䨝ࣁ coverage/ ፓ袅ҁ毆戔҂Ӿ叨ኞ HTML 粚ጱ䁭ޞ物

    View Slide

  66. Codecov

    View Slide

  67. Codecov

    View Slide

  68. 㷢ᘍ虻碘

    View Slide

  69. 㷢ᘍ虻碘
    • Give Jest Another Go

    https://medium.com/@jrwebdev/give-jest-another-go-86ca3d00f75
    • Unit Test Redux Container Components - Part 1

    http://www.wsbrunson.com/react/redux/test/2016/05/08/testing-redux-containers.html
    • React.js 101 - React 介手獈槹硽䋊

    https://github.com/kdchang/reactjs101/tree/master/Appendix03
    • Testing React Components With Enzyme

    http://codeheaven.io/testing-react-components-with-enzyme/
    • 介手໛礍 Mocha 䋿ֺ硽纷

    http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html
    • Testing Your React (and redux) Applications (Youtube video)

    https://www.youtube.com/watch?v=n49QKIzS_Ik
    • 獮ᒒ介手ૡٍ墋㻌碉ቘ޾穉斃

    https://github.com/ellisMing/introduction-angular-test#獮ᒒ介手ૡٍ墋㻌碉ቘ޾穉斃

    View Slide

  70. Thanks! <(_ _)>

    View Slide