原文發於個人博客:https://github.com/hwen/blogS...html
關於這個 cnode 上就有個頗有意思的討論前端
看完這個應該會有結論?若是沒有,就回帖跟別人探討下~webpack
測試有分爲git
單元測試(單測)github
集成測試web
系統測試express
主要區別是單測傾向於測試模塊內部運行邏輯及功能,集成測試傾向於模塊間互相組合跟調用的測試。
系統測試(固然你要說,還有自動化測試)是對整個系統的測試,主要由測試人員而非開發人員負責。後端
本文只討論單測的範疇,對集成測試有興趣的話,能夠看下 Vue 的集成測試代碼。api
測試本質上就是假定一個輸入,而後判斷獲得預期的輸出。而前端與後端相比,夾雜着瀏覽器 DOM 操做,異步請求,
瀏覽器兼容性等方面的。要我來講,比後端寫單測要麻煩多了。。。
不過如今前端的單測已經發展得比較完善了,已經有一套比較完整的工具鏈,來完成各類需求。
目前比較流行的測試框架有:
jasmine: 自帶斷言(assert),mock 功能
mocha:框架不帶斷言和mock功能,須要結合其餘工具。mocha 是 tj 大神寫的(tj 就是那個寫了express、koa、n、co、ejs的人。。。)
用得比較多的就上面兩個,還有一些用得比較少的,好比 Qunit、intern
框架的實現原理其實就是檢測內部運行的代碼是否有拋出異常。而斷言庫若是沒有獲得預期的輸入時,就會拋出異常,給框架檢測到。
PS.想要學 mocha 和單測寫法,最好的資源就是 express 框架的測試代碼(狼叔推薦,親測很不錯)
chai:目前比較流行的斷言庫,支持 TDD(assert),BDD(expect、should)兩種風格
shouldjs:也是 tj 寫的,說實話我比較喜歡這個,可是有坑。。。後面會說到。。。
expectjs:基本是 shouldjs 的縮水版
assert:node 的核心模塊,node 環境能夠直接使用
sinon.js:只用過這個,其餘不大清楚。不過這個是目前最多人用的,基本夠了。支持 spies
, stub
, fake XMLHttpRequest
, Fake server
, Fake time
,很強大
(並非學會,就是這麼耿直 _(:з)∠)_,手是誰???)
使用的是:karma + mocha + chai + sinon(若是以前沒了解過這幾個,能夠邊寫邊看文檔,這樣學會快不少)
完整的例子能夠在這裏找到:GitHub 項目
建議把項目 clone 下來本身跑一遍,而後能夠本身加一些特效(啊,不對,是代碼纔對。。。
詳細代碼,及配置見 源碼
it('test dom', () => { const div = document.getElementById('test') const content = div.innerHTML content.should.be.equal('here') setDivContent() const after = div.innerHTML after.should.be.equal('hallo world') })
it('test async', done => { getTopics() .then(res => { res.success.should.be.equal(true) done() }) .catch(err => { info(err) done(err) }) })
當你的單元測試越寫越多時,想測試新寫的單測是否正確時,能夠用 mocha 的 only
這樣作的好處有二:第一屏蔽其餘測試可使測試速度變得更快,第二屏蔽其餘測試,能夠在你新寫的測試錯誤時
肯定這個錯誤不是被其餘測試所影響致使的。
用法
describe.only('something', function() { // 只會跑包在裏面的測試 })
或者
it.only('do do', () => { // 只會跑這一個測試 })
要開啓 debug 的話,先在 karma.conf.js
把 singleRun
改爲 false
而後,看圖(懶得打字了 (:з)∠)
生成覆蓋率報告也是至關簡單,不過有個要注意的地方就是
如今前端代碼不少都是通過 webpack
,babel
編譯的,生成的代碼會多了不少二外的代碼
要解決這個問題使用babel-plugin-istanbul
來替代karma-coverage
就能夠了
preprocessors: { 'src/**/*.js': ['webpack', 'coverage'], 'test/*.test.js': ['webpack'] }
將 karma-coverage 去掉,變成
preprocessors: { 'src/**/*.js': ['webpack'], 'test/*.test.js': ['webpack'] }
而後在 webpack 配置添加 istanbul 插件
use: { loader: 'babel-loader', options: { plugins: ['istanbul'] } }
最後能夠生成覆蓋率報告
另外有不少工具能夠對生成的覆蓋率報告進行進一步的分析,好比最多見的
你會在 Github 上常常見到的圖標
這個就是利用報告裏的lcovonly
分析生成的
coverageReporter: { dir: 'test/coverage/', reporters: [ { type: 'html', subdir: 'report-html' }, { type: 'lcovonly', subdir: '.', file: 'report-lcovonly.txt' }, // 這裏,你能夠重命名 file { type: 'text-summary', subdir: '.', file: 'text-summary.txt' } ] }
測試時若是有涉及瀏覽器事件(addEventListener),記得測試完移除掉,否則會對其餘的測試形成影響(afterEach -> removeEventListener)
mocha 裏使用箭頭函數須要注意,由於箭頭函數的 this 指向是靜態的,因此 this 並不指向 mocha(沒有 mocha 上下文)
上面有說到,若是測試的是通過編譯的代碼,須要進行一些配置,目前的辦法是用babel-plugin-istanbul
代替karma-cover
來檢測覆蓋率
前面有說到,爲何不用 should.js
??由於若是你用 ES6 的語法寫單測(webpack 編譯),用 import should-sinon 會報錯。。(是否是由於 tj 大神寫完東西不喜歡維護的習慣致使should.js支持性很差???)