項目中屢次使用karma + webpack + chai + mocha + sinon作單元測試。配置腳本都是從別人的項目中拷貝來的,對其中部分庫是幹什麼的,以及這些庫之間是如何融合在一塊兒工做的具體機制都是隻知其一;不知其二。本文探索karma如何與測試框架合做, 但願能深刻一點(本文記錄我的學習的過程,或有謬誤,請多指教。)html
咱們從最原始的js測試出發,假設我寫了2個函數:前端
// 待測試的代碼 function add(x, y) { return x + y } function sub(x, y) { return x - y + 1 // 很明顯這個函數寫錯了 }
咱們如今想測試他們,怎麼測試呢?webpack
咱們給待測試的函數設置了一些輸入,而後咱們觀察他們是否能給出正確的輸出。git
// 測試用例 var testCase1 = function() { var sum = add(1, 3) if (sum === 4) { console.log('OK') } else { console.log('Error') } } var testCase2 = function() { var sum = sub(5, 2) if (sum === 3) { console.log('OK') } else { console.log('error') } }
而後咱們能夠寫一個html頁面,加載待測試函數和測試用例,在添加上這2行運行測試用例的代碼:github
// 測試執行 testCase1() testCase2()
最後在網頁console咱們觀察結果:web
好的,咱們發現咱們的sub
函數寫錯了。npm
這彷佛很蠢,而後確實就是一個測試的過程,固然這個過程並不能用於工程,它有有不少問題:瀏覽器
這些問題均可以經過咱們上面提到的karma工具鏈來解決。框架
這玩意是什麼?官方說法: a test runner
。那又是什麼? 能不能說人話?按我我的理解,Test runner的主要功能就是執行測試用例並輸出測試結果的一個庫,也就是說Karma至少解決了上面提到問題裏的1,2和3。
用過karma的人都知道: 經過安裝一些庫,作一些配置,karma就能與不少測試框架協做從而能讓咱們經過一條命令直接完成測試的執行和結果輸出,那麼Karma若是作到的呢?函數
咱們改造一下上面實例的代碼,建立一個前端項目:
內容很簡單:
// src/index.js // src裏是源碼 function add(x, y) { return x + y } function sub(x, y) { return x - y + 1 }
// test/index.js // 測試用例代碼寫在這裏, window.__karma__相關的代碼先忽略 var testCase1 = function() { var sum = add(1, 3) if (sum === 4) { window.__karma__.result({ id: 1, description: '1 + 3 = 4', suite: ['leon'], log: ['OK'], success: true, skipped: false }) } else { console.log('Error') } } var testCase2 = function() { var sum = sub(5, 2) if (sum === 3) { console.log('Success') } else { window.__karma__.result({ id: 2, description: '5 - 2 = ' + sum, suite: ['leon'], log: ['OK'], success: false, skipped: false }) } } window.__karma__.start = function () { window.__karma__.info({ total: 2 }) testCase1() testCase2() window.__karma__.complete() }
// karma.conf.js module.exports = function(config) { config.set({ .... // list of files / patterns to load in the browser files: [ 'src/index.js', 'test/index.js' ], ... }) }
如今咱們的工程結構清晰了.
src
下是源碼test
下是測試用例karma.conf.js
裏是測試配置(咱們使用最簡單的設置,基本就只指定了一個要加載的文件)咱們執行一下測試(npm run test
)看看結果:
karma start karma.conf.js --log-level debug
2個測試用例都被執行了,結果也清晰的打印在了console上了。
咱們經過命令(npm run tdd)把測試網頁跑起來, 而後打開測試的頁面http://localhost:9876/debug.html
能夠看到
原來每次咱們執行Karma start命令的時候,Karma就是自動把咱們在karma.conf.js
的files
字段裏的文件都加載到網頁裏了。
實際上File 字段的註釋已經說得很清楚了: list of files / patterns to load in the browser
Karma如何知道測試的開始,結束,每條用例的結果的呢?Karma的文檔裏說得也很清楚(可是彷佛不太準確)
上面貼test/index.js
代碼的時候我就提到了,window.__karma__
相關的代碼先忽略。實際上這個是karma給測試用例或者更高級一點的測試框架的通訊接口:
從上面的例子中,能夠很明顯的體會到這些功能:
咱們實現一個window.__karma__.start函數,以便Karma框架能夠調用,在這個函數裏咱們首先告訴Karma咱們一共有2個測試用例,而後咱們再去執行這2個測試用例,最後通知karma測試結束了。在測試用例裏,咱們再也不簡單的使用cossole.log來打印結果,而是用window.__karma__.result
把詳細的結果通知給Karma
// Karma框架調用 window.__karma__.start = function () { // 咱們有2個測試用例 window.__karma__.info({ total: 2 }) // 執行用例 testCase1() testCase2() // 通知karma測試結束了 window.__karma__.complete() }
可是以前咱們寫測試用例的時候沒寫過這些__karma__.xxx函數啊!是啊,通常咱們是不會像例子裏這樣本身寫測試用例,本身管理的,而都是用mocha這樣的測試框架的。
例子:
var add = require('./add.js'); var expect = require('chai').expect; describe('加法函數的測試', function() { it('1 加 1 應該等於 2', function() { expect(add(1, 1)).to.be.equal(2); }); });
實際上在用mocha
的時候,咱們都是要安裝一個庫叫karma-mocha. 這個庫就是把這些__karma__.xxx的函數都封裝了一遍, 因此咱們都只顧着寫mocha
的測試用例就好了。
看一眼這個庫的說明:Adapter for Mocha testing framework.
原來是這個意思啊!!
不少時候咱們都用一些現成的東西,以致於都不會去深究一些事情的本質,因此在遇到深一點層次的問題的時候都會以爲無所適從。有時候事情的本質實際上沒那麼複雜,咱們只是確少去發掘的勇氣和精力。