前端單元測試框架介紹

做爲一個前端,一開始並不知道單元測試的好處,以爲費時費力,效果也不明顯,直到有個模塊由於性能問題進行了一次重構,被折磨得筋疲力盡的時候,才發現單元測試的好處,能夠說,有了單元測試,才能面對其餘同事寫的或者n年之前的代碼,放心大膽的對其進行持續的維護甚至重構。html

  • 單元測試有別於集成測試,是對最小可測試單元(通常爲單個函數或小組件)進行檢查和驗證。功能越簡單越好,單個驗證其餘變量影響越少越好,這樣能達到最好的效果。好的單元測試用例能夠充當開發文檔供後人閱讀。

斷言庫 chai

單元測試的核心就是斷言,經過斷言來判斷代碼是否達到目的前端

node內置斷言assert,如下圖爲最簡單例子,若是錯誤會拋出異常 vue

chai這個斷言庫很全很強大,提供了經常使用的assert should expect斷言關鍵字node

各種的用法就不提了,方法比較簡單,一查便知。 assert最簡單,不過目前expect用得比較多,例如 expert(xxx).toBe(xxxx) 可是 egg官網推薦assert,理由是簡單,不用記一些複雜api。

Mocha

Mocha是老牌的庫,簡單全面易用,目前公司就在用Mocha+chai測試前端數據邏輯,用來測試node,util裏面的函數均可以,測試組件須要搭配其餘框架。react

Mocha測試的鉤子 Mocha在describe塊之中,提供測試用例的四個鉤子:before()、after()、beforeEach()和afterEach()。 能夠用before鉤子提早把測試環境和數據準備好,beforeEach鉤子能夠在每一個測試用例前準備一個或多個新的對象,防止被前面的用例污染ios

describe('測試index.js',()=> {
  before(()=>console.info("在本區塊的全部測試用例以前執行"))
  after(()=>console.info("在本區塊的全部測試用例以後執行"))
  beforeEach(()=>console.info("在本區塊的每一個測試用例以前執行"))
  afterEach(()=>console.info("在本區塊的每一個測試用例以後執行"))
  describe('測試addNum函數', ()=> {
    it('兩數相加結果爲兩個數字的和', ()=> {
      assert.equal(addNum(1,2),3)
    })
  })
})
複製代碼

最後,Mocha默認每一個測試用例最多執行2000毫秒,若是到時沒有獲得結果,就報錯, 並且Mocha默認會高亮顯示超過75毫秒的測試用例,可修改chrome

sinon

sinon具備很是有特點的spies, stub, mock三個功能,有興趣的能夠嘗試手寫實現。vue-cli

  • spies的概念

spies => 間諜函數,間諜函數是Sinon最簡單的部分,其它的功能都是創建在spies之上的,spies的主要用途是收集有關函數調用的信息,例如是否調用了函數等。spies的實現監聽的基礎上是不會影響函數自己正常調用(被監聽的函數的上下文關係不會被影響)。json

  • stub的概念

stub徹底取代了這個函數,並且擁有spies的全部功能。當使用stub時,函數將不具備原始的功能,而是替換後的函數。redux

  • mock的概念

mock與stub的功能同樣都是用來替換指定的函數,若是你想替換掉一個對象中的多個方法,這時mock就能夠發揮做用了,可是若是僅僅是替換對象中的一個函數,那麼stub更加簡單易用,當咱們使用mock的時候應該十分當心,由於大量的替換原有代碼邏輯,會致使test變的脆弱。

nock或者moxios

用來模擬發送網絡請求,須要替代後臺接口時使用。

Karma

非jsdom,提供真實瀏覽器環境,因爲目前各種框架已經比較完善了,如今已經基本被排除在主流框架以外

redux-mock-store

顧名思義,用於模擬 redux 中的 store。因爲工做中一直用mobx,這裏很少作介紹了

jasmine

使用與jest相似,之前一般和karma配合,大而全的測試框架(jest)成爲主流後,用的少了

jest

jest 是facebook推出的一款測試框架,集成了Mocha,chai,jsdom,sinon等功能。因此剛入門的同窗若是想應用直接能夠上jest。

react官方腳手架自帶jest,vue-cli3.0中也集成了單元測試框架,選擇的時候會問你選mocha+chai仍是jest。

  • 運行命令 jest 後會自動運行項目下全部.test.js和.spec.js這種格式的文件。jest的配置默認只要在package.json中配置便可,如只測test文件夾下test.jsx文件
"jest": {
    "testRegex": "/test/*.test.jsx?$"
 }
複製代碼
  • 集成expect斷言

  • 異步處理 對於callback採用done()確保完成測試,對於promise自動處理,遇到reject自動拋出錯誤,async+await同理

  • Jest 中的 mock , 相似於sinon的 sinon,而且還能夠模擬axios的網絡請求

  • 快照snapshot 對組件或者數據生成一份快照,每次測試自動深比較,不一致就報錯

  • 能夠生成測試覆蓋率報告,只須要在jest命令後加入 --coverage便可

jest --coverage
複製代碼

enzyme && test-utils

airbnb公司推出的 enzyme ,專門用來測試react組件,相對應vue中也有test-utils包,基本是同樣的功能,也是對組件掛載後進行事件觸發、元素存在等判斷。

這裏以enzyme爲例講解,enzyme主要提供三種渲染方式:render、mount、shallow,存在如下區別:

render渲染結果是普通的html結構,shallow和mount對組件的渲染結果是react樹,若是你用過chrome的react devtool插件,他的渲染結果就是react devtool tab下查看的組件結構。

shallow和mount的返回結果是個被封裝的ReactWrapper,能夠進行多種相似JQ的鏈式操做,譬如find()、parents()、children()等選擇器進行元素查找;state()、props()進行數據查找,setState()、setprops()操做數據;simulate()模擬事件觸發。

shallow只渲染當前組件,只對當前組件作斷言,不會產生子組件;mount會渲染當前組件以及全部子組件,對全部子組件也能夠作上述操做。通常交互測試都會關心到子組件,我使用的都是mount。可是mount耗時更長,內存啥的也都佔用的更多,若是不必操做和斷言子組件,通常使用shallow。

總結

單元測試屬於須要投入,可是看不見產出的工做,因此直接選擇最簡潔的框架,節約時間,纔是提高kpi的關鍵,如今的框架愈來愈趨向簡單和人性化,因此若是工做中使用,直接選jest類集成框架就好。

我在的toB傳統軟件服務公司,前端的穩定性更加劇要,在一個產品快速迭代期後,單元測試也會逐步進行覆蓋util模塊和model層(響應action的數據變化處理),其它則須要看迭代排期,常常重構的基礎公共組件也會排上。每一個公司需求不一樣,若是是上線就撤的項目,能夠不用部署測試。因此你們考慮引進單元測試前,請靈活考慮成本和收益。

相關文章
相關標籤/搜索