在 2017 年學習 React + Redux 的一些建議(下篇)

發表於2017-09-11

68747470733a2f2f7777772e726f62696e776965727563682e64652f696d672f706f7374732f746970732d746f2d6c6561726e2d72656163742d72656475782f62616e6e65722e6a7067關於測試的一些學習建議

我們可以組合使用一些測試工具來幫助測試 JS 程式碼,一般使用 Mocha/Chai 或是 Karma/Jasmine 。而如果當你想測試 angular 的程式碼時,你會發現還有更多的測試工具。不過對於 React 應用的測試,比較推薦使用 Airbnb 團隊出品的 anzyme 來進行元件的測試,以保住元件的穩定可靠,目前使用非常廣泛;而另一種方式是使用 Facebookjest 來進行測試。

可能很多同學都覺得應該選擇以上的某一個測試庫來進行測試工作,不過,你也可以將 anzymejest 結合起來一起使用。特別是在進行一些 snapshot 快照測試的時候,兩種都是互補的,它們已經是 React 應用測試中大家公認的標準庫了。

sinon 也是個非常優秀的測試輔助工具,可以幫助我們在 spy、stub、mock 等測試階段提供相應的工具輔助測試。如果對這幾個概念不太清晰,可以看看這裡

另外,在這裡給你隆重的給你推薦一篇 A. Sharif 寫的 Some Thoughts On Testing React/Redux Applications,滿滿的乾貨分享哦。

多一些元件的單元測試,少一些整合測試

Enzyme 可以幫助我們實現元件的單元測試和整合測試。這裡我們可以通過三種方式來渲染元件:

  • shallow()
  • mount()
  • render()

shallow() 只能用來渲染不包含 children 的元件,mount() 則能夠渲染所有的子元件。所以單元測試的時候可以使用 shallow()mount() 則一般用於整合測試。整合測試往往是很容易被割裂的,因為他需要測試由一組或是多個元件樹組合的場景,所以整合測試一般維護成本是比較高的。所以我們可以多做一些小巧的單元測試,少做一些重要的整合測試。

第三種測試的方式是使用 render() 方法,具有類似 mount()方法的功能,不過 mount() 能夠訪問到元件的生命週期方法,比如 componentDidUpdate等。

正如這個 issue 中提出的 API differences between render and mount/shallow,可以總結出:

  • 使用 shallow 開始測試用例
  • 如果 componentDidMount or componentDidUpdate 等方法也需要測試,那麼使用 mount 方法吧
  • 如果要測試元件生命週期方法、子元件的行為等,使用 mount 方法吧
  • 如果想更高效能的測試子元件,並且對元件的生命週期等方法不怎麼關注,那麼使用 render 方法吧

保證測試用例簡單、最小顆粒度

否則的話你需要為此付出很高的維護成本。

確認每個元件是否都有執行過單元測試,確認每個 props 和 callbacks 都在整合測試的時候傳遞給了對應的子元件。

為了保證元件測試用例的小顆粒度和簡單化,你需要熟悉一下 selectorsEnzyme 提供了豐富的 selector 去深入元件樹。

另外,建議使用 sinon 來測試 callbacks 回撥函式,不要在元件中測試業務邏輯,這真不是個好注意。而是應該將業務邏輯從元件中解耦並對其進行測試。

最後,Facebook 出品的 Jest 也能在初期幫助我們更加輕量的執行測試,你可以非常簡單就設定好 snapshot test,這樣當元件的輸出改變的話測試用例會自動的報出失敗的結果,並且能夠獲取到錯誤資訊。

擁抱 TDD(測試驅動開發)

所有的人都可能會對你說:你應該按測試驅動的模式來進行開發。但是,幾乎沒幾個人會這麼,專案需求如山的積壓,上線的指令碼火急火燎,測試驅動?玩呢?!可能大部分小夥伴都是這樣的心聲。

不過,如果你能夠清晰的在 React + Redux 的應用中使用對應的測試方案對每個部分都進行測試,你就能夠非常輕鬆的實現 TDD。儘管你會發現 reducer 的測試和元件的測試是很不一樣的,但其實每種型別(reducer、component、…. )的測試模式其實都是一樣的。

就拿 reducer 的測試為例吧,一般是期望 reducer(state, action) === newState,其實這種方式和 (input) => output 的模式是一樣的。如果你要測試 state 的不可變性的話,建議你可以使用 deep-freeze,可以看下以下示例程式碼:

如果你能夠很清晰的知道如何測試應用中的每一個部分,那就最好採用 TDD。

多元件測試

關於資源載入的選擇

React 雖然是個 library,但是它的生態圈非常的豐富,會有非常多的可擴充套件框架或類庫可以加入使用,但是千萬別太快的加入這些擴充套件方案。並且每次新加入一個模組的時候,要在團隊裡面確認每個人都是清楚瞭解的。特別是對於 Redux 本身的一些生態擴充套件,會有非常多的一些小模組,比如下面這些:

  • 在大家還沒開始寫 action creatorsreducers 之前,就不要新增 redux-actions
  • 在大家還沒寫出第一個自己的 form 表單和表單驗證的時候,就不要加入 redux-form
  • 在大家還沒開始寫自己的 selectors 之前,就不要加入 reselect
  • 在大家還麼開始寫第一個高階元件 HOC 之前,就不要加入 recompose
  • …..

同時,關注一些大牛的最佳實踐,並且建立你自己的最佳實踐。不過得確保團隊中其他小夥伴也能理解。定義清晰的命名規則和目錄結構,並且在專案做一些升級的時候得把這些約定提前討論清楚。

保持持續的技術學習熱情

結束語

全文完結,感謝你的閱讀,希望整個系列的文章對你今後的學習有所幫助。

如果你想系統學習 React + Redux 技術棧的所有內容,請點我前往

相關文章