做爲一個前端,一開始並不知道單元測試的好處,以爲費時費力,效果也不明顯,直到有個模塊由於性能問題進行了一次重構,被折磨得筋疲力盡的時候,才發現單元測試的好處,能夠說,有了單元測試,才能面對其餘同事寫的或者n年之前的代碼,放心大膽的對其進行持續的維護甚至重構。html
單元測試的核心就是斷言,經過斷言來判斷代碼是否達到目的前端
node內置斷言assert,如下圖爲最簡單例子,若是錯誤會拋出異常 vue
chai
這個斷言庫很全很強大,提供了經常使用的assert should expect斷言關鍵字node
expert(xxx).toBe(xxxx)
可是
egg官網推薦assert,理由是簡單,不用記一些複雜api。
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具備很是有特點的spies, stub, mock三個功能,有興趣的能夠嘗試手寫實現。vue-cli
spies => 間諜函數,間諜函數是Sinon最簡單的部分,其它的功能都是創建在spies之上的,spies的主要用途是收集有關函數調用的信息,例如是否調用了函數等。spies的實現監聽的基礎上是不會影響函數自己正常調用(被監聽的函數的上下文關係不會被影響)。json
stub徹底取代了這個函數,並且擁有spies的全部功能。當使用stub時,函數將不具備原始的功能,而是替換後的函數。redux
mock與stub的功能同樣都是用來替換指定的函數,若是你想替換掉一個對象中的多個方法,這時mock就能夠發揮做用了,可是若是僅僅是替換對象中的一個函數,那麼stub更加簡單易用,當咱們使用mock的時候應該十分當心,由於大量的替換原有代碼邏輯,會致使test變的脆弱。
用來模擬發送網絡請求,須要替代後臺接口時使用。
非jsdom,提供真實瀏覽器環境,因爲目前各種框架已經比較完善了,如今已經基本被排除在主流框架以外
顧名思義,用於模擬 redux 中的 store。因爲工做中一直用mobx,這裏很少作介紹了
使用與jest相似,之前一般和karma配合,大而全的測試框架(jest)成爲主流後,用的少了
jest 是facebook推出的一款測試框架,集成了Mocha,chai,jsdom,sinon等功能。因此剛入門的同窗若是想應用直接能夠上jest。
react官方腳手架自帶jest,vue-cli3.0中也集成了單元測試框架,選擇的時候會問你選mocha+chai仍是jest。
"jest": {
"testRegex": "/test/*.test.jsx?$"
}
複製代碼
集成expect斷言
異步處理 對於callback採用done()確保完成測試,對於promise自動處理,遇到reject自動拋出錯誤,async+await同理
Jest 中的 mock , 相似於sinon的 sinon,而且還能夠模擬axios的網絡請求
快照snapshot 對組件或者數據生成一份快照,每次測試自動深比較,不一致就報錯
能夠生成測試覆蓋率報告,只須要在jest命令後加入 --coverage便可
jest --coverage
複製代碼
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的數據變化處理),其它則須要看迭代排期,常常重構的基礎公共組件也會排上。每一個公司需求不一樣,若是是上線就撤的項目,能夠不用部署測試。因此你們考慮引進單元測試前,請靈活考慮成本和收益。