使用 Jest 進行 Front-End Unit Test

9b2c27c2123feb9b02865c44b86456d0?s=47 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/

9b2c27c2123feb9b02865c44b86456d0?s=128

Patrick Wang

September 26, 2016
Tweet

Transcript

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

  2. य़姛

  3. • Frameworks • Jest च๜戔ਧ • Enzyme • 承ဩ膏憒㳷 •

    ݱ蟂獤 Test ᯿讨膏ොဩ • ٌ犢ੜದૣ • Coverage
  4. Frameworks

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

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

  7. Frameworks • E2E Test • Casper.js • Protractor • Nightwatch.js

    • CodeceptJS http://reactmad-testing.surge.sh/#/5
  8. Jest च๜戔ਧ

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

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

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

    scss 䲆礯 介手脻๜ጱ䲆ݷ pattern
  12. jest configuration jest/setupTests.js 蝡螲ฎ傶ԧ mock ധ localStorage

  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.
  14. Enzyme

  15. Enzyme • by Airbnb • ੗蕕ԧ React ጱਥො介手ૡٍ牧䢐磪觊犲 jQuery ጱ

    螡䢔瑊 API牧介手砰䌃Ӥๅො׎
  16. Enzyme - find • ֵአ React TestUtils 螡玲粬ਧፓ秂ጱ API物
 TestUtils.findRenderedDOMComponentWithXXXX

    • ֵአ Enzyme ݝᥝ component.find(selector) ܨݢ物
  17. Enzyme • shallow • render • mount

  18. Enzyme - shallow • ੗蕕ਥොጱ shallow rendering • ݝ჉礕ᒫӞ䍅牧犋჉礕ৼزկ •

    蝧ଶ盠 • 犋ᓕ child component ጱᤈ傶牧介手᯿讨ݝฎ component ๜蛪
  19. Enzyme - render • 觊犲 shallow牧ֵ֕አ Cheerio ୚砻 • 犋ݝ჉礕Ӟ䍅

    • API 蚤 shallow च๜ӤӞ膌
  20. Enzyme - mount • Full rendering • ፥䋿ጱ DOM ℄讨

    • మᥝ介手膏 DOM ጱ԰㵕膏盅媲叨ኞጱ虋玕ҁই Click 盅㳫ᴻԧӞ㮆 list ጱ殻ፓ҂ • మᥝ介手ਠ碉ጱኞ޸蝰๗
  21. 承ဩ膏憒㳷

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

  25. Jest ൉׀ጱ API • describe, it • xdescribe, xit -

    䧙碻᪡螂介手碻ֵአ • fit - 㰍᪒種ྦྷ介手 • beforeEach - ࣁྯ㮆介手ԏ獮᮷䁆ᤈ • afterEach - ࣁྯ㮆介手ԏ盅᮷䁆ᤈ http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html
  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
  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
  28. 䌕礯ֵአጱ介手䲆礯޸ݷ憒㳷 (2/2) • 舙襑ਧ嬝盄裾ጱ fake data牧ୌ捍ݚक़ୌӞඪ䲆礯硯ᗝ牧㪔 硯ᗝࣁݶӞ䍅牐ٚෝ介手䲆礯Ӿ import 蝱㬵ֵአ牐 •

    犥 reselect ጱ newsByCat 傶ֺ牧׎ୌ缏ԧ物 • newsByCat-newsByIdItemData.js物
 newsById 奾䯤ጱ؃虻碘 • newsByCat-makeState.js物
 蜍獈 newsByCat-newsByIdItemData.js ጱ؃虻碘盅牧叨 ڊӞ犩؃ state ׀扗 reselect 介手ֵአ
  29. ݱ蟂獤 Test ᯿讨膏ොဩ

  30. Component 介手᯿讨 1. Snapshot 介手 (Jest v14.0 ڊ匍) • 穉䌘叨ኞ

    HTML ጱ奾ຎฎ玽膏Ӥ稞盠ᆙፘᒧ • 犖磪Ոአࣁ reducer • https://facebook.github.io/jest/blog/2016/07/27/jest-14.html/ 2. Simulate ᤈ傶介手 ࢩ種盠ᆙ犖ᥝ蝱 git
  31. Component - snapshot snapshot

  32. Component - simulate (with mount)

  33. Container 介手᯿讨 1. Container 膏ٌ Component ᮷磪ᤩ render ڊ㬵 •

    襑አ <Provider> ۱蚏㬵 2. ᤩ Mock ጱ Component 磪ᤩ call Ӟ稞
  34. Container 伛猋؃虻碘牏አ Provider ۱蚏㬵牏㯽獈 context

  35. Container ᛔ૩ mock createStore

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

  37. Reducer 介手᯿讨 1. 蜍獈 initial state 膏 action 盅牧蜴ࢧ毆๗ጱ state

    2. 蝫媲蜍獈 state 膏 action 盅牧膏 snapshots ፘᒧ
  38. Reducer

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

  40. snapshot አෝ reducer snapshot

  41. Action 介手᯿讨 1. 䁆ᤈ action 盅牧蜴ࢧ毆๗ጱ object (type 膏 payloads)

    2. 瞚Ӥ牧֕Ӿ樌妿螂 mock 螂ጱ ajax
  42. Action

  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
  44. Action - mock ajax (2/4)

  45. Action - mock ajax (3/4)

  46. Action - mock ajax (4/4) ಩ܻ๜ ajax ጱ蟂犩 mock ധ

    犖ݢ犥አ ES7 await/async
  47. Reselect 介手᯿讨 1. 懯ᓒ奾ຎ膏毆๗ፘᒧ 2. 蜍獈ፘݶጱ独牧犋䨝᯿碝懯ᓒ (recomputations)

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

  49. Router (1/4) 介手᯿讨 1. params / path ፘᒧ 2. property

    ፘᒧҁই物䢐磪 hideTopAd҂ 3. Component ፘᒧ
  50. Router (2/4)

  51. Router (3/4)

  52. Router (4/4)

  53. ٌ犢ੜದૣ

  54. jest.mock(module_path, fn) (1/2) • Jest 粬ᜋԏӞ牧虏介手䌕ဳࣁ匍ࣁ介手ጱ秇奲๜蛪牧 import ጱ module mock

    ധ牧螨ع୽段介手Ӿጱ秇 奲牐 • ֕ Jest v15 蚏牧automocking 毆戔ฎ橕ധጱ牐ҁਥ ො藯ก҂
  55. jest.mock(module_path, fn) (2/2)

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

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

    ga/piwik ጱ纷ୗ嘨牧֕介手碻䷱磪஠ᥝ
 斉獈 ga牧ݝᥝ jest.fn() mock 蚏㬵疰অ牐
  58. jest.fn() (2/2) 介手ݢ犥介扗 mock 螂ጱ function ฎ玽ᤩ call牫
 ᤩ call

    ጱ碻狡ᴫ癲Ջ讕㷢碍牫 ࣁ beforeEach Ӿአ mockFn.mockClear() 嘦狒ྯ稞᮷ ᯿ᗝ制眲ҁ㯽獈㷢碍牏稞碍҂牐
  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
  60. timer ፘ橕 mock (2/3) https://facebook.github.io/jest/docs/timer-mocks.html#content

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

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

  63. Coverage

  64. Coverage jest 獉ୌ coverage牐౯㮉犖ࣁ package.json 戔ਧঅ script ԧ牐 䨝礬硁 package.json

    Ӿ jest.collectCoverageFrom 戔ਧጱፓ袅塅瑻懯ᓒ coverage牐
 叨ኞ蝡䰬ጱ奾ຎ物
  65. Coverage 犖䨝ࣁ coverage/ ፓ袅ҁ毆戔҂Ӿ叨ኞ HTML 粚ጱ䁭ޞ物

  66. Codecov

  67. Codecov

  68. 㷢ᘍ虻碘

  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#獮ᒒ介手ૡٍ墋㻌碉ቘ޾穉斃
  70. Thanks! <(_ _)>