本文簡單介紹了NodeJS裡最常用的測試框架--mocha的安裝以及簡單的使用方法,支援直接在browser上跑Javascript程式碼測試,這裡推薦給大家
NodeJS裡最常用的測試框架估計就是mocha了。它支援多種node的assert libs, 同時支援非同步和同步的測試,同時支援多種方式匯出結果,也支援直接在browser上執行Javascript程式碼測試。
本文範例多源自於官網範例,部分範例結合需求或自己的感想有所改變。更多介紹請看 官方網址:Mocha on Github
Installation:
當你成功安裝nodejs v0.10 和 npm後執行下面這條指令。
# npm install -g mocha
p.s. Ubuntu的注意apt來源裡的nodejs版本會比較舊,某些module會不支持,請從nodejs官網進行原始碼安裝。
First step to Mocha:
以下為最簡單的一個mocha範例:
var assert = require("assert"); describe('Array', function(){ describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ assert.equal(-1, [1,2,3].indexOf(5)); assert.equal(-1, [1,2,3].indexOf(0)); }) }) });
describe (moduleName, testDetails) 由上述程式碼可看出,describe是可以嵌套的,例如上述程式碼嵌套的兩個describe就可以理解成測試人員希望測試Array模組下的#indexOf() 子模組。 module_name 是可以隨便取的,關鍵是要讓人讀懂就好。
it (info, function) 具體的測試語句會放在it的回呼函數裡,一般來說info字串會寫期望的正確輸出的簡要一句話文字說明。當該it block內的test failed的時候控制台就會把詳細資料印出來。一般是從最外層的describe的module_name開始輸出(可以理解成沿著路徑或遞迴鏈結或回呼鏈),最後輸出info,表示該期望的info內容沒有被滿足。一個it對應一個實際的test case
assert.equal (exp1, exp2) 斷言判斷exp1結果是否等於exp2, 這裡採取的等於判斷是== 而並非 === 。即 assert.equal(1, ‘1') 認為是True。這只是nodejs裡的assert.js的一種斷言形式,下文會提到同樣比較常用的should.js。
如果exp1和exp2都是字串,字串比較出錯時則控制台會用顏色把相異的部分標出來。
Asynchronous
Frist step 中的程式碼顯然是個 Synchronous 的程式碼,那麼對於非同步程式碼該怎麼做呢?很簡單,在你最深處的回呼函數中加done()表示結束。
fs = require('fs'); describe('File', function(){ describe('#readFile()', function(){ it('should read test.ls without error', function(done){ fs.readFile('test.ls', function(err){ if (err) throw err; done(); }); }) }) })
done ()
依照瀑布流程式設計習慣,取名done是表示你回呼的最深處,也就是結束寫嵌套回呼函數。但對於回調鏈來說done實際上意味著告訴mocha從這裡開始測試,一層層回調回去。
上例程式碼是test pass的,我們試著把test.ls改成不存在的test.as。便會回到具體的錯誤位置。
這裡可能會有個疑問,假如我有兩個非同步函數(兩條分叉的回呼鏈),那我該在哪裡加done()呢?其實這個時候就不應該在一個it裡面存在兩個要測試的函數,事實上一個it裡面只能呼叫一次done,當你呼叫多次done的話mocha會拋出錯誤。所以應該類似這樣:
fs = require('fs'); describe('File', function(){ describe('#readFile()', function(){ it('should read test.ls without error', function(done){ fs.readFile('test.ls', function(err){ if (err) throw err; done(); }); }) it('should read test.js without error', function(done){ fs.readFile('test.js', function(err){ if (err) throw err; done(); }); }) }) })
Pending
即省去測試細節只保留函數體。一般適用情況例如負責測試框架的寫好框架讓組員去實現細節,或者測試細節尚未完全正確實現先註釋以免影響全局測試情況。這種時候mocha會默認該測試pass。
作用有點像Python的pass。
describe('Array', function(){ describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ }) }) });
Exclusive && Inclusive
其實很好理解,分別對應only和skip函數。
fs = require('fs'); describe('File', function(){ describe('#readFile()', function(){ it.skip('should read test.ls without error', function(done){ fs.readFile('test.ls', function(err){ if (err) throw err; done(); }); }) it('should read test.js without error', function(done){ }) }) })
上面的程式碼只會有一個test complete, 只有only的會被執行,另一個會被忽略掉。每個函數裡只能有一個only。如果是it.skip ,那麼該case就會被忽略。
only和skip共用沒有什麼實際意義,因為only的作用會把skip屏蔽掉。
fs = require('fs'); describe('File', function(){ describe('#readFile()', function(){ it.skip('should read test.ls without error', function(done){ fs.readFile('test.as', function(err){ if (err) throw err; done(); }); }) it('should read test.js without error', function(done){ }) }) })
上面的程式碼儘管test.as不存在,但是由於skip,依然會顯示test complete。
Before && After
單元測試裡常會用到before和after。 mocha同時也提供了beforeEach()和afterEach()。
這裡為方便閱讀用livescript表示,!->可理解成function(){}。細節無需細讀,只需透過框架了解這幾個函數如何使用便可。
require! assert require! fs can = it describe 'Array', !-> beforeEach !-> console.log 'beforeEach Array' before !-> console.log 'before Array' before !-> console.log 'before Array second time' after !-> console.log 'after Array' describe '#indexOf()', !-> can 'should return -1 when the value is not present', !-> assert.equal -1, [1,2,3].indexOf 0 can 'should return 1 when the value is not present', !-> describe 'File', !-> beforeEach !-> console.log 'beforeEach file test!' afterEach !-> console.log 'afterEach File test!' describe '#readFile()', !-> can 'should read test.ls without error', !(done)-> fs.readFile 'test.ls', !(err)-> if err throw err done! can 'should read test.js without error', !(done)-> fs.readFile 'test.js', !(err)-> if err throw err done!
由結果可知(after的使用與before同理),
#beforeEach會對當前describe下的所有子case生效。
before和after的程式碼沒有特殊順序要求。
同一個describe下可以有多個before,執行順序與程式碼順序相同。
同一個describe下的執行順序為before, beforeEach, afterEach, after
當一個it有多個before的時候,執行順序從最外圍的describe的before開始,其餘同理。
Test Driven Develop (TDD)
mocha默认的模式是Behavior Driven Develop (BDD),要想执行TDD的test的时候需要加上参数,如
mocha -u tdd test.js
前文所讲的describe, it, before, after等都属于BDD的范畴,对于TDD,我们用suite, test, setup, teardown。样例代码如下:
suite 'Array', !-> setup !-> console.log 'setup' teardown !-> console.log 'teardown' suite '#indexOf()', !-> test 'should return -1 when not present', !-> assert.equal -1, [1,2,3].indexOf 4
以上是詳解NodeJS測試框架mocha入門的詳細內容。更多資訊請關注PHP中文網其他相關文章!