使用 Jest 進行 Front-End Unit Test(線上 React 讀書會版)

使用 Jest 進行 Front-End Unit Test(線上 React 讀書會版)

* 前言
* Frameworks
* Jest 基本設定
* Enzyme
* 語法與規則
* 各部分 Test 重點與方法(以 react + redux 為例)
* 其他 jest 小技巧
* Coverage

9b2c27c2123feb9b02865c44b86456d0?s=128

Patrick Wang

August 14, 2017
Tweet

Transcript

  1. 2.

    Patrick Wang a.k.a. patw, ⼩小p • Front-end Developer • GitHub:

    github.com/patw0929 • Website: patw.me • Blog: blog.patw.me • Linkedin: www.linkedin.com/in/patrickpatw/
  2. 4.

    • 前⾔言 • Frameworks • Jest 基本設定 • Enzyme •

    語法與規則 • 各部分 Test 重點與⽅方法(以 react + redux 為例例) • 其他 jest ⼩小技巧 • Coverage
  3. 14.
  4. 18.

    E2E Testing • Casper.js • Protractor • Nightwatch.js • CodeceptJS

    • Appium / Detox (Mobile App) http://reactmad-testing.surge.sh/#/5
  5. 20.

    安裝 & 設定 jest & enable babel .babelrc 現在 create-react-app

    也都會幫你建好 https://facebook.github.io/jest/docs/getting-started.html
  6. 24.

    jest configuration - transform config/jest/cssTransform.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.
  7. 25.
  8. 27.

    Enzyme - find • 使⽤用 React TestUtils 選取特定⽬目標的 API:
 TestUtils.findRenderedDOMComponentWithXXXX

    • 使⽤用 Enzyme 只要 component.find(selector) 即可: http://airbnb.io/enzyme/docs/api/selector.html
  9. 29.

    Enzyme - shallow • 封裝官⽅方的 shallow rendering • 只渲染第⼀一層,不渲染⼦子元件 •

    速度快 • 不管 child component 的⾏行行為,測試重點只是 component 本⾝身
  10. 31.

    Enzyme - mount • Full rendering • 真實的 DOM 節點

    • 想要測試與 DOM 的互動與後續產⽣生的變化(如 Click 後刪除了了⼀一個 list 的項⽬目) • 想要測試完整的⽣生命週期
  11. 33.

    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
  12. 34.

    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); }); });
  13. 36.

    Jest 提供的 API • describe, it • xdescribe, xit -

    暫時跳過測試時使⽤用 • fit - 僅跑此段測試 • beforeEach - 在每個測試之前都執⾏行行 • afterEach - 在每個測試之後都執⾏行行 http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html https://facebook.github.io/jest/docs/api.html#content
  14. 37.

    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 https://facebook.github.io/jest/docs/expect.html#content
  15. 38.

    專案使⽤用的測試檔案命名規則 (1/2) • 欲測試的 source 同層開⼀一個 __tests__ ⽬目錄 • 檔名:{source

    檔名}.test.js • 另外,因⽬目前使⽤用 Ducks: Redux Reducer Bundles 的規範撰 寫 redux,故 reducers 與 actions 的命名規範如下: • Actions: {source 檔名}.actions.test.js • Reducers: {source 檔名}.reducer.test.js
  16. 43.

    Component 測試重點 1. Snapshot 測試 (Jest v14.0 出現) • 比對產⽣生的結果是否與上次快照相符

    • https://facebook.github.io/jest/blog/2016/07/27/jest-14.html/ • https://www.youtube.com/watch?v=HAuXJVI_bUs 2. Simulate ⾏行行為測試(例例如 click 之後改變了了 state) 因此快照也要進 git 在測 reducer 也可以⽤用喔!!
  17. 48.

    Container 測試重點 1. Container 與其 Component 都有被 render 出來來 •

    需⽤用 <Provider> 包起來來 2. 被 Mock 的 Component 有被 call ⼀一次 3. 呼叫 action 後,dispatch 有被執⾏行行
  18. 53.

    Reducer 測試重點 1. 輸入 initial state 與 action 後,返回預期的 state

    2. 連續輸入 state 與 action 後,與 snapshots 相符
  19. 54.
  20. 59.
  21. 60.

    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
  22. 65.

    jest.mock(module_path, fn) (1/2) • Jest 特⾊色之⼀一,讓測試專注在現在測試的模組本⾝身, import 的 module mock

    掉,避免影響測試中的模 組。 • 但 Jest v15 起,automocking 預設是關掉的。(官 ⽅方說明)
  23. 70.

    jest.fn() (2/2) 測試可以測該 mock 過的 function 是否被 call?
 被 call

    的時候附帶什什麼參參數? 在 beforeEach 中⽤用 mockFn.mockClear() 確保每次 都重置狀狀態(傳入參參數、次數)。
  24. 71.

    timer 相關 mock (1/3) 針對 timer 也可以 mock,jest.useFakeTimers() 原⽣生的⽅方法 (setTimeout,

    setInterval, clearTimeout, clearInterval) 就真的要跑那麼 久,⽤用 Jest 快轉吧! https://facebook.github.io/jest/docs/timer-mocks.html#content
  25. 77.
  26. 78.

    Coverage jest 內建 coverage。我們也在 package.json 設定好 script 了了。 會根據 package.json

    中 collectCoverageFrom 設定的⽬目錄範圍計算 coverage。
 產⽣生這樣的結果:
  27. 80.
  28. 81.
  29. 84.

    參參考資料 • 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/ • Introduction to Jest testing framework (Youtube video)
 https://www.youtube.com/watch?v=tvy0bSgwtTo • Testing Your React (and redux) Applications (Youtube video)
 https://www.youtube.com/watch?v=n49QKIzS_Ik • 前端測試⼯工具簡單整理理和比較
 https://github.com/ellisMing/introduction-angular-test#前端測試⼯工具簡單整理理和比較