本文為實踐的產(chǎn)物,總結(jié)從搭建到使用過程中遇到的問題,初學(xué)者可以參考。
- Jest 和 Enzyme 的基本介紹
- 測試環(huán)境搭建
- 測試腳本編寫
- 運行并調(diào)試
- 匹配器使用
- 測試異步代碼
- 遇到的問題
- 參考資料
Jest、Enzyme介紹
Jest是Facebook發(fā)布的一個開源的、基于Jasmine框架的JavaScript單元測試工具,支持?jǐn)嘌?、仿真、快照測試、測試覆蓋率報告等。
Enzyme獲得React 官方的推薦,Airbnb開源的React測試類庫Enzyme提供了一套簡介強大的API,并通過jQuery風(fēng)格的方式進行DOM處理,開發(fā)體檢十分友好。
強烈推薦閱讀使用jest+enzyme進行react項目測試 - 介紹篇
測試環(huán)境搭建
在開發(fā)React應(yīng)用的基礎(chǔ)上,需要安裝Jest、Enzyme以及對應(yīng)的babel-jest。
使用 yarn 安裝 Jest︰
yarn add --dev jest enzyme babel-jest
或 npm:
npm install --save-dev jest enzyme babel-jest
將下面的配置部分添加到package.json 里面:
{
"scripts": {
"test": "jest"
}
"jest": {
"moduleFileExtensions": [
"js",
"jsx"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
".*\\.(css|less|scss)$": "<rootDir>/__mocks__/styleMock.js"
},
"transform": {
"^.+\\.js$": "babel-jest"
}
},
}
- moduleFileExtensions:代表支持加載的文件名,與Webpack中的resolve.extensions類似
- moduleNameMapper:代表需要被Mock的資源名稱。如果需要Mock靜態(tài)資源(如less、scss等),需要配置Mock的路徑<rootDir>/mocks/xxMock.js
- transform:用于編譯 ES6/ES7 語法,需配合 babel-jest使用
這三個是常用的配置,更多 Jest 配置見官方文檔:Jest Configuration
然后,創(chuàng)建xx.test.js的文件,寫實際的測試邏輯
最后,運行yarn test
測試腳本編寫
強烈推薦閱讀使用jest+enzyme進行react項目測試 - 測試手法篇
測試用例寫法總結(jié)
組件UI測試用snapshot
snapshot可以測試到組件的渲染結(jié)果是否符合預(yù)期,預(yù)期就是指你上一次錄入保存的結(jié)果,toMatchSnapshot方法會去幫你對比這次將要生成的結(jié)構(gòu)與上次的區(qū)別
需要注意的是一個足夠健壯的測試應(yīng)該覆蓋到所有的渲染請況,也就是如果你的組件根據(jù)props傳入的參數(shù)渲染結(jié)果可能不同,這樣的情況必須寫多個測試案例都覆蓋到。-
DOM交互測試用Jest+Enzyme
enzyme有3種渲染方式:render、mount、shallow
render、mount、shallow的區(qū)別
render采用的是第三方庫Cheerio的渲染,渲染結(jié)果是普通的html結(jié)構(gòu),對于snapshot使用render比較合適。shallow和mount對組件的渲染結(jié)果不是html的dom樹,而是react樹,如果你chrome裝了react devtool插件,他的渲染結(jié)果就是react devtool tab下查看的組件結(jié)構(gòu),而render函數(shù)的結(jié)果是element tab下查看的結(jié)果。
這些只是渲染結(jié)果上的差別,更大的差別是shallow和mount的結(jié)果是個被封裝的ReactWrapper,可以進行多種操作,譬如find()、parents()、children()等選擇器進行元素查找;state()、props()進行數(shù)據(jù)查找,setState()、setprops()操作數(shù)據(jù);simulate()模擬事件觸發(fā)。
shallow只渲染當(dāng)前組件,只能能對當(dāng)前組件做斷言;mount會渲染當(dāng)前組件以及所有子組件,對所有子組件也可以做上述操作。一般交互測試都會關(guān)心到子組件,我使用的都是mount。但是mount耗時更長,內(nèi)存啥的也都占用的更多,如果沒必要操作和斷言子組件,可以使用shallow。
交互測試
主要利用simulate()接口模擬事件,實際上simulate是通過觸發(fā)事件綁定函數(shù),來模擬事件的觸發(fā)。觸發(fā)事件后,去判斷props上特定函數(shù)是否被調(diào)用,傳參是否正確;組件狀態(tài)是否發(fā)生預(yù)料之中的修改;某個dom節(jié)點是否存在是否符合期望。mock請求
需要mock掉真正的http請求,模擬返回值。不用擔(dān)心不準(zhǔn)確,你只用保證請求時的參數(shù)符合期望就好,mock的返回值按預(yù)期編寫就好,置于這些請求是否真的能返回這些結(jié)果,是接口測試改干的活。
運行并調(diào)試
在運行測試腳本過程,Jest 的錯誤提示信息友好,通過錯誤信息一般都能找到問題的所在。 同時 Jest 還提供了生成測試覆蓋率報告的命令,只需要在package.json 里配置{ "scripts": { "test": "jest --coverage " } 即可生成。會在終端中顯示如下報告:

而且還會在項目中生成 coverage 文件夾,非常方便。
匹配器使用
推薦閱讀:
前端測試框架Jest系列教程 -- Matchers(匹配器)
Javascript單元測試工具-Jest 學(xué)習(xí)筆記(一)
測試異步代碼
推薦閱讀:
Javascript單元測試工具-Jest 學(xué)習(xí)筆記(一)
學(xué)習(xí)Jest——語法篇
遇到的問題
Image.onload不能被監(jiān)聽到
解決辦法參考:https://zhuanlan.zhihu.com/p/37329102
我采用了自己 mock Image 構(gòu)造函數(shù)方案
最后,在寫測試用例過程中,不知道用什么匹配器,可以來Jest官網(wǎng)搜羅一圈https://jestjs.io/docs/zh-Hans/expect
不知道使用Enzyme什么API時,也來Enzyme搜羅一圈http://airbnb.io/enzyme/docs/api/
總能找到你想要的~