本次翻譯時間爲2016年9月底,目前Mocha的版本爲3.1.0。 官方文檔地址: mochajs.org/ —— Aweyjavascript
Mocha是一個可以運行在Node和瀏覽器中的多功能的JavaScript測試框架,它讓異步測試簡單且有趣。Mocha連續地運行測試,並給出靈活而精確的報告,同時可以將錯誤精確地映射到測試用例上。它託管在GitHub上。php
以爲Mocha頗有幫助?成爲支持者並以每個月捐贈的形式支持Mocha。css
公司正在使用Mocha?詢問你的上司或者市場部看看他們是否捐贈過Mocha。(若是捐贈過)大家公司的LOGO會展現在npmjs.com和咱們的github倉庫html
略。 本次翻譯並未徹底按照官方文檔的文檔結構進行。java
npm 全局安裝:node
npm install --global mocha
複製代碼
或者做爲開發依賴安裝在項目中:jquery
npm install mocha --save-dev
複製代碼
安裝Mocha v3.0.0或者更新的版本,你須要v1.4.0或者更新版本的npm。此外,運行Mocha的Node版本不能低於v0.10linux
Mocha也能經過Bower安裝,還可經過cdnjs進行引用。git
npm install mocha
mkdir test
$EDITOR test/test.js # 或者使用你喜歡的編輯器打開
複製代碼
在編輯器中:github
var assert = require('assert')
describe('Array', function () {
describe('#indexOf()', function() {
it('未找到值時應當返回-1', function () {
assert.equal(-1, [1, 2, 3].indexOf(4))
})
})
})
複製代碼
回到命令行:
Array
#indexOf()
√ 未找到值時應當返回-1
1 passing (9ms)
複製代碼
Mocha容許你使用你喜歡的斷言庫。在以後的例子中,咱們使用了Node中內置的斷言模塊——但一般狀況下,只要它能拋出異常就行[1]。這意味着你可使用下列斷言庫:
用Mocha測試異步代碼簡單的不要不要的!測試運行完了調用一下回調函數就行。只須要在it()
中添加一個回調[2],Mocha就知道應該等到這個回調被調用時才結束這個測試用例的運行。
describe('User', function () {
describe(#'save()', function () {
it('應當正常保存', function () {
var user = new User('Luna')
user.save(function (err) {
if (err) done(err)
else done()
})
})
})
})
複製代碼
簡便起見,done()
函數接受一個error參數,因此上面的代碼能夠這麼寫:
describe('User', function () {
describe(#'save()', function () {
it('應當正常保存', function () {
var user = new User('Luna')
user.save(done)
})
})
複製代碼
有時,與其使用done()
回調函數,你會想在你的異步代碼中返回一個Promise[3],當你正在測試的API是返回一個Promise而不是使用回調時這會頗有幫助:
beforeEach(function () {
return db.clear()
.then(function () {
return db.save([tobi, loki, jane])
})
})
describe('#find()', function () {
it('返回匹配的記錄', function () {
return db.find({ type: 'User' }).should.eventually.have.length(3)
})
})
複製代碼
接下來的例子將會使用chai-as-promised來得到流暢的promise斷言
在Mocha 3.0及更新的版本中,同時返回一個Promise和調用done()
會致使一個異常,下面的代碼是錯誤的:
const assert = require('assert')
it('應該結束這個測試用例', function (done) {
return new Promise(function (resolve) {
assert.ok(true)
resolve()
})
.then(done)
})
複製代碼
上面的測試會報錯:Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.
。在v3.0.0如下的版本,done()
會被忽略(而不會報錯)。
當測試同步代碼的時候,省略回調函數[4],Mocha就會自動執行下一條測試。
describe('Array', function () {
describe('#indexOf()', function () {
it('沒有找到時應當返回-1', function () {
[1, 2, 3].indexOf(5).should.equal(-1)
[1, 2, 3].indexOf(0).should.equal(-1)
})
})
})
複製代碼
不建議在Mocha中使用箭頭函數(「lambdas」)。因爲(箭頭函數特殊的)this
綁定語法,箭頭函數沒法訪問Mocha的上下文。例如,下面的代碼會由於使用了箭頭函數而執行失敗:
describe('my suit', () => {
it('my test', () => {
// 應當設置1000毫秒延遲,而不是執行失敗
this.timeout(1000)
assert.ok(true)
})
})
複製代碼
固然若是你不須要使用Mocha的上下文,使用lambdas就沒有問題了。然而這樣的作的結果是你的測試代碼將難以重構
Mocha默認使用「BDD」風格的接口,提供了before()
,after()
,beforeEach()
和afterEach()
四個鉤子函數。這些函數能夠用來(在測試前)作預處理工做或在測試後清理工做。
describe('hooks', function () {
before(function () {
// 在這個做用域的全部測試用例運行以前運行
})
after(function () {
// 在這個做用域的全部測試用例運行完以後運行
})
beforeEach(function () {
// 在這個做用域的每個測試用例運行以前運行
})
afterEach(function () {
// 在這個做用域的每個測試用例運行以後運行
})
// 測試用例
})
複製代碼
測試用例和測試的鉤子能夠混合排列。(相同的)鉤子函數會按照它們的書寫順序運行;(總體的運行順序是)全部的
before()
鉤子運行一次,而後是beforeEach()
鉤子,測試用例,afterEach()
鉤子(循環運行),最後是after()
鉤子(運行一次)
全部的鉤子在調用時均可以提供一個可選的「描述信息」的參數,以便在你的測試中更精確地定位錯誤。若是給一個鉤子函數傳入一個命名函數,當未提供「描述信息」參數的時候,這個命名函數的名稱將被做爲描述信息。
beforeEach(function () {
// beforeEach hook
})
beforeEach(function namedFun () {
// beforeEach: namedFun
})
beforeEach('一些描述信息' ,function () {
// beforEach: 一些描述信息
})
複製代碼
全部鉤子(before()
, after()
, beforeEach()
, afterEach()
)既能夠是同步的也能夠是異步的,(這一點上)它們的行爲與普通的測試用例很是類似[5]:
describe('鏈接', function () {
var db = new Connection,
tobi = new User('tobi'),
loki = new User('loki'),
jane = newUser('jane')
beforeEach(function (done) {
db.clear(function (err) {
if (err) return done(err)
db.save([tobi, loki, jane], done)
})
})
describe('#find()', function () {
it('返回匹配的記錄', function (done) {
db.find({type: 'User'}, function (err, res) {
if (err) return done(err)
res.should.have.length(3)
})
})
})
})
複製代碼
你能夠在任意(測試)文件中添加「全局」級別的鉤子函數,例如,在全部describe()
做用域以外添加一個beforeEach()
,它的回調函數會在全部的測試用例運行以前運行,不管(這個測試用例)處在哪一個文件(這是由於Mocha有一個隱藏的describe()
做用域,稱爲「根測試套件 root suite」)。
beforeEach(function () {
console.log('在全部文件的全部測試用例以前運行')
})
複製代碼
若是你須要在全部測試套件運行以前進行一些異步操做,你能夠延遲根測試套件。以--delay
參數運行mocha
[6],這會在全局注入一個特殊的回調函數run()
:
setTimeout(function () {
// 一些設置
describe('個人測試套件', function () {
// ...
})
run()
}, 5000)
複製代碼
「Pending」——「有人最終會編寫這些測試用例」——沒有傳入回調函數的測試用例[7]:
describe('Array', function () {
describe('#indexOf()', function () {
// 掛起的測試用例
it('未找到時應當返回-1')
})
})
複製代碼
掛起的測試用例會在報告中出現「pending」狀態。
經過向測試套件或測試用例函數添加.only
後綴,獨佔特性容許你只運行指定的測試套件或測試用例。下面是一個獨佔測試套件的例子:
describe('Array', function (){
describe.only('#indexOf()', function () {
// ...
})
})
複製代碼
注意:全部嵌套(在.only
套件中的)測試套件仍舊會運行 下面是一個運行單個測試用例的例子:
describe('Array', function (){
describe('#indexOf()', function () {
it.only('除非找到不然返回-1', function () {
// ...
})
it('找到後應當返回下標', function () {
// ...
})
})
})
複製代碼
在v3.0.0版本之前,only()
使用字符串匹配來決定哪些測試須要執行。v3.0.0之後的版本only()
可使用屢次來定義測試用例的子集去運行:
describe('Array', function() {
describe('#indexOf()', function() {
it.only('should return -1 unless present', function() {
// 這個測試用例會運行
})
it.only('should return the index when present', function() {
// 這個測試用例也會運行
})
it('should return -1 if called with a non-Array context', function() {
// 這個測試用例不會運行
})
})
})
複製代碼
你也能夠選擇多個測試套件:
describe('Array', function() {
describe.only('#indexOf()', function() {
it('should return -1 unless present', function() {
// 這個測試用例會運行
})
it('should return the index when present', function() {
// 這個測試用例也會運行
})
})
describe.only('#concat()', function () {
it('should return a new Array', function () {
// 這個測試用例也會運行
})
})
describe('#slice()', function () {
it('should return a new Array', function () {
// 這個測試用例不會運行
})
})
})
複製代碼
但測試會存在優先級[8]:
describe('Array', function() {
describe.only('#indexOf()', function() {
it.only('should return -1 unless present', function() {
// 這個測試用例會運行
})
it('should return the index when present', function() {
// 這個測試用例不會運行
})
})
})
複製代碼
注意,若是提供了鉤子函數,鉤子函數仍會執行
注意不要把
.only
提交到版本控制上,除非你明確知道你在作什麼
這個功能是only()
的反面。經過後綴skip()
就可讓Mocha忽略這個測試套件或測試用例。全部被跳過的測試都會被標記爲pending
狀態並體如今報告中。下面是一個跳過一整個測試套件的例子:
describe('Array', function() {
describe.skip('#indexOf()', function() {
// ...
})
})
複製代碼
下面是一個跳過測試用例的例子:
describe('Array', function() {
describe('#indexOf()', function() {
it.skip('should return -1 unless present', function() {
// 這個測試用例不會運行
})
it('should return the index when present', function() {
// 這個測試用例會運行
})
})
})
複製代碼
最佳實踐:使用
skip()
而不是直接將測試註釋掉
你也可使用this.skip()
在運行時跳過測試。若是測試須要的環境或配置沒辦法提早檢測,能夠考慮使用運行時跳過。例如:
it('應該僅在正確的環境配置中測試', function () {
if(/*測試環境正確*/) {
// 編寫斷言
} else {
this.skip()
}
})
複製代碼
由於這個測試什麼也沒作[9],它會被報告爲passing
。
最佳實踐:不要什麼也不作[10]!一個測試應當編寫斷言或者使用
this.skip()
若是想以這種方式跳過多個測試[11],能夠在一個befor()
鉤子函數中調用this.skip()
:
before(function() {
if (/* check test environment */) {
// setup code
} else {
this.skip()
}
})
複製代碼
在Mocha v3.0.0版本之前,鉤子函數和異步測試中不支持
this.skip()
你能夠選擇將失敗的測試重試必定的次數。這個特性被設計用於資源(數據)不容易被仿造的端到端(end-to-end)測試(functional tests/Selenium…)。不推薦將這個特性用於單元測試。
這個特性會從新運行beforeEach()
/afterEach()
鉤子,但不會運行before()
/after()
鉤子。
注意:下面的例子使用了Selenium webdriver(爲Promise鏈式調用改寫了Mocha的全局鉤子)。
describe('retries', function() {
// 測試套件中的全部測試用例將被重試4次
this.retries(4)
beforeEach(function () {
browser.get('http://www.yahoo.com');
})
it('should succeed on the 3rd try', function () {
// 指定這個測試用例僅重試2次
this.retries(2)
expect($('.foo').isDisplayed()).to.eventually.be.true
})
})
複製代碼
可使用Function.prototype.call
和函數表達式來定義測試套件和測試用例,以動態生成測試而不須要其它的特殊語法——簡單的JavaScript就能用於實現你可能在其它測試框架中見到過的相似「參數化」測試的功能。
例如:
var assert = require('chai').assert
function add() {
return Array.prototype.slice.call(arguments).reduce(function(prev, curr) {
return prev + curr
}, 0)
}
describe('add()', function() {
var tests = [
{args: [1, 2], expected: 3},
{args: [1, 2, 3], expected: 6},
{args: [1, 2, 3, 4], expected: 10}
]
tests.forEach(function(test) {
it('correctly adds ' + test.args.length + ' args', function() {
var res = add.apply(null, test.args)
assert.equal(res, test.expected)
})
})
})
複製代碼
上面的代碼將會生成一個帶有三個測試用例的測試套件:
$ mocha
add()
✓ correctly adds 2 args
✓ correctly adds 3 args
✓ correctly adds 4 args
複製代碼
許多測試報告都會顯示測試耗時,而且標記出那些耗時較長的測試,就像下面的報告顯示的那樣:
你可使用slow()
方法來定義到底多久纔算「耗時較長」:
describe('something slow', function() {
this.slow(10000)
it('它的耗時應該足夠我去作個三明治了', function() {
// ...
})
})
複製代碼
套件級別的超時應用於整個測試套件,你也能夠經過this.timeout(0)
來取消超時限制。若是沒有覆蓋這個值的話[12],全部嵌套的測試套件和測試用例都會繼承這個超時限制。
describe('a suite of tests', function() {
this.timeout(500)
it('應當不超過500毫秒', function(done){
setTimeout(done, 300)
})
it('也應當不超過500毫秒', function(done){
setTimeout(done, 250)
})
})
複製代碼
也能夠對單一用例設置超時時間,或者經過this.timeout(0)
來取消超時限制:
it('應該不超過500毫秒', function(done){
this.timeout(500)
setTimeout(done, 300)
})
複製代碼
固然也能夠設置鉤子級別的超時:
describe('一個測試套件', function() {
beforeEach(function(done) {
this.timeout(3000); // 一個用時很長的環境設置操做.
setTimeout(done, 2500)
})
})
複製代碼
一樣,使用this.timeout(0)
來取消超時限制
在v3.0.0或更新的版本中,給
this.timeout()
傳遞一個大於最大延遲值的參數會讓超時限制失效
Mocha支持斷言庫拋出的AssertionErrors
的兩個屬性err.expected
和err.actual
。Mocha會嘗試顯示指望(的代碼)和斷言庫真正看到的的代碼之間的差別。這裏有一個「string」差別的例子:
Usage: mocha [debug] [options] [files]
Commands:
init <path> initialize a client-side mocha setup at <path>
Options:
-h, --help 顯示使用幫助
-V, --version 顯示版本信息
-A, --async-only 強制全部測試帶有回調(異步)或返回一個promise
-c, --colors 強制啓用顏色
-C, --no-colors 強制關閉顏色
-G, --growl 啓用彈出消息
-O, --reporter-options <k=v,k2=v2,...> 測試報告工具詳細設置
-R, --reporter <name> 指定測試報告工具
-S, --sort 測試文件排序
-b, --bail 第一次測試不經過當即結束測試
-d, --debug 開啓node的debugger模式, 同node --debug
-g, --grep <pattern> 只運行匹配<pattern>的測試
-f, --fgrep <string> 只運行包含<string>的測試
-gc, --expose-gc 暴露gc擴展
-i, --invert 反轉--grep 和--fgrep 匹配
-r, --require <name> 加載指定模塊
-s, --slow <ms> 以毫秒爲單位定義"慢" 測試門檻 [75]
-t, --timeout <ms> 以毫秒爲單位設置測試用例超時時間 [2000]
-u, --ui <name> 指定用戶接口 (bdd|tdd|qunit|exports)
-w, --watch 監測文件變更
--check-leaks 檢查全局變量泄露
--full-trace 顯示完整的跟蹤堆棧
--compilers <ext>:<module>,... 使用指定的模塊編譯文件
--debug-brk 在首行啓用node的debugger斷點
--globals <names> allow the given comma-delimited global [names](沒辦法強行翻譯了)
--es_staging 開啓全部過期的特性
--harmony<_classes,_generators,...> all node --harmony* flags are available
--preserve-symlinks 命令模塊加載器在解析和緩存模塊時保留符號連接
--icu-data-dir 包括ICU數據
--inline-diffs 在行內顯示實際/預期的字符差別
--interfaces 顯示可用的接口(bdd|tdd|qunit|exports)
--no-deprecation 禁用警告
--no-exit 請求一個完全的事件循環終止: Mocha不會調用 process.exit
--no-timeouts 禁用超時, 隱含 --debug
--opts <path> 指定選項路徑
--perf-basic-prof enable perf linux profiler (basic support)
--prof 記錄統計分析信息
--log-timer-events 記錄包含外部回調的時間點
--recursive 包含子目錄
--reporters 顯示可用的測試報告工具
--retries <times> 設置重試未經過的測試用例的次數
--throw-deprecation 當使用了廢棄的方法時拋出異常
--trace 追蹤函數借調
--trace-deprecation 顯示廢棄的跟蹤堆棧
--use_strict 強制嚴格模式
--watch-extensions <ext>,... --watch 上附加的監控擴展
--delay 等待異步套件定義
複製代碼
-w
,--watch
初始化後,監測文件變更運行測試
--compilers
CoffeeScript再也不被直接支持。這類預編譯語言可使用相應的編譯器擴展來使用,好比CS1.6:--compilers coffee:coffee-script
和CS1.7+:--compilers coffee:coffee-script/register
babel-register
若是你的ES6模塊是以.js
爲擴展名的,你能夠npm install --save-dev babel-register
,而後--require babel-register; --compilers
就能夠指定文件擴展名
-b
,--ball
只對首個異常感興趣?使用--bail
-d
,--debug
開啓node的調試模式,這會用node debug <file ...>
來執行你的腳本,容許你逐行調試代碼並用debugger
聲明來打斷點。注意mocha debug
和mocha --debug
的區別:mocha debug
會啓動node內置的debug客戶端,mocha --debug
則容許你使用其它調試工具——好比Blink Developer Tools。
--globals <name>
接受一個以逗號分隔的全局變量名,例如,若是你的應用有意暴露一個全局變量名app
或YUI
,你可能就會使用--globals app,YUI
。它還接受通配符。--globals '*bar'
會匹配foobar, barbar
等。你也能夠簡單地傳入*
來忽略全部全局變量。
check-leaks
在運行測試時,Mocha默認不會檢查全局變量泄露,可使用--check-leaks
來開啓這一功能,使用--globals
來指定接受的全局變量好比--globals jQuery,MyLib
。
-r
,--require
<module-name>
--require
選項對諸如should.js一類的庫頗有用,因此你可使用--require should
而不是在每個測試文件中都調用require('should')
。須要注意的是由於should
是加強了Object.prototype
因此能夠正常使用,然而假如你但願訪問某模塊的輸出你就只能require
它們了,好比var should = require('should')
。此外,還可使用相對路徑,好比--reqiure ./test/helper.js
-u
,--ui
<name>
--ui
選項讓你指定想使用的接口,默認爲「bdd」。
-R
,--reporter
<name>
--reporter
選項容許你指定但願使用的報告器,默認爲「spec」。這個標記也能夠用來使用第三方的報告器。例如,若是你npm install mocha-locv-reporter
,你能夠--reporter mocha-locv-reporter
。
-t
,--timeout
<ms>
指定測試用例超時時間,默認爲2秒。你能夠傳入毫秒數或者一個帶s
單位後綴的秒數進行覆蓋,例如--timeout 2s
和--timeout 2000
是等價的。
s
,--slow
<ms>
指定「慢」測試閾值,默認爲75毫秒。Mocha用這個去高亮那些耗時過長的測試。
-g
,--grep
<pattern>
指定--grep
選項讓Mocha只運行匹配<pattern>
的測試,<pattern>
將會做爲正則表達式進行解析。
假如,像下面的片斷那樣,你有一些「api」相關的測試和一些「app」相關的測試;則前者可使用--grep api
來運行,後者可以使用--grep --app
來運行
describe('api', function() {
describe('GET /api/users', function() {
it('respond with an array of users', function() {
// ...
})
})
})
describe('app', function() {
describe('GET /users', function() {
it('respond with an array of users', function() {
// ...
})
})
})
複製代碼
Mocha的「接口」系統容許開發者選擇習慣的風格或DSL。Mocha有BDD,TDD,Exports,QUnit和Require風格的接口。
BDD接口提供describe()
,context()
,it()
,specify()
,before()
,after()
,beforeEach()
和afterEach()
。
context()
只是describe()
的別名,兩者表現也是一致的;它只是爲了讓測試可讀性更高。一樣specify()
也是it()
的別名。
前文全部的示例都是使用BDD接口編寫的
describe('Array', function() {
before(function() {
// ...
})
describe('#indexOf()', function() {
context('when not present', function() {
it('should not throw an error', function() {
(function() {
[1,2,3].indexOf(4)
}).should.not.throw()
})
it('should return -1', function() {
[1,2,3].indexOf(4).should.equal(-1);
})
})
context('when present', function() {
it('should return the index where the element first appears in the array', function() {
[1,2,3].indexOf(3).should.equal(2)
})
})
})
})
複製代碼
TDD接口提供suite()
,test()
,suiteSetup()
,suiteTeardown()
,setup
和teardown()
:
suite('Array', function() {
setup(function() {
// ...
})
suite('#indexOf()', function() {
test('should return -1 when not present', function() {
assert.equal(-1, [1,2,3].indexOf(4));
})
})
})
複製代碼
EXPORTS接口很像Mocha的前身expresso,鍵值before
,after
,beforeEach
,afterEach
是特殊用例,對象類型的屬性值是測試套件,方法類型的屬性值是測試用例:
module.exports = {
before: function() {
// ...
},
'Array': {
'#indexOf()': {
'should return -1 when not present': function() {
[1,2,3].indexOf(4).should.equal(-1)
}
}
}
}
複製代碼
類QUnit接口與QUnit的「扁平化」外觀相匹配[14],測試套件只須要簡單地在測試用例以前定義就行。和TDD相似,它使用suite()
和test()
,但又相似於BDD,也包含了before()
,after()
,beforeEach()
和afterEach()
。
function ok(expr, msg) {
if (!expr) throw new Error(msg)
}
suite('Array')
test('#length', function() {
var arr = [1,2,3]
ok(arr.length == 3)
})
test('#indexOf()', function() {
var arr = [1,2,3]
ok(arr.indexOf(1) == 0)
ok(arr.indexOf(2) == 1)
ok(arr.indexOf(3) == 2)
})
suite('String')
test('#length', function() {
ok('foo'.length == 3)
})
複製代碼
require
風格接口容許你直接用require
語句引入describe
等函數並在任意位置使用它們。當你但願在你的測試中禁用全局變量時這也會頗有用。
注意,require
風格接口不能經過node直接運行,必須經過Mocha運行
var testCase = require('mocha').describe
var pre = require('mocha').before
var assertions = require('mocha').it
var assert = require('chai').assert
testCase('Array', function() {
pre(function() {
// ...
});
testCase('#indexOf()', function() {
assertions('should return -1 when not present', function() {
assert.equal([1,2,3].indexOf(4), -1)
})
})
})
複製代碼
Mocha的測試報告與命令行窗口適配,且當標準輸出串口沒有關聯到打印機時始終禁用ANSI-escape顏色。
這是默認的測試報告。「SPEC」測試報告輸出與測試用例一致的嵌套視圖。
Dot Matrix(或者Dot)測試報告使用一串簡單字符來表示測試用例,失敗的(failing)以紅色歎號(!)表示,掛起的(pedding)以藍色逗號(,)表示,長時的以黃色表示。當你但願最小化輸出的時候這就很好。
NYAN測試報告就是你想的那樣(一隻貓):
TAP測試報告的輸出很適合Test-Anything-Protocol的用戶。
landing Strip(landing)測試報告是一個非正式的測試報告器,它用unicode字符模仿了飛機降落的情景。
list測試報告輸出一個測試用例經過或失敗的簡潔列表,並在底部輸出失敗用例的詳情。
progress測試報告展現一個簡單進度條。
JSON測試報告在測試完成後輸出一個大JSON對象。
JSON stream測試報告輸出根據「事件」斷行了的JSON,以「start」事件開始,緊跟着測試經過或失敗,最後是「end」事件。
min測試報告僅顯示結果摘要,固然也輸出失敗時的錯誤信息。當與--watch
一塊兒使用時很棒,它會清空你的命令行讓測試摘要始終顯示在最上方。
doc測試報告輸出一個層級化的HTML來表示你的測試結果。使用header,footer和一些樣式來包裹測試結果,而後你就有了一份驚豔的測試報告文檔!
例如,假定你有下面的JavaScript:
describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
[1,2,3].indexOf(5).should.equal(-1);
[1,2,3].indexOf(0).should.equal(-1);
});
});
});
複製代碼
在命令行輸入mocha --reporter doc array
會輸出:
<section class="suite">
<h1>Array</h1>
<dl>
<section class="suite">
<h1>#indexOf()</h1>
<dl>
<dt>should return -1 when the value is not present</dt>
<dd><pre><code>[1,2,3].indexOf(5).should.equal(-1);
[1,2,3].indexOf(0).should.equal(-1);</code></pre></dd>
</dl>
</section>
</dl>
</section>
複製代碼
The SuperAgent request library test documentation was generated with Mocha’s doc reporter using this simple make target:
test-docs:
$(MAKE) test REPORTER=doc \
| cat docs/head.html - docs/tail.html \
> docs/test.html
複製代碼
View the entire Makefile for reference.
markdown測試報告爲你的測試討價能生成一個markdown TOC。當你但願將你的測試結果放在Github的wiki或倉庫中時,這會很好用。這是一個例子的連接測試輸出
HTML測試報告是當前Mocha惟一支持的瀏覽器測試報告,長得像這樣:
XUnit測試報告也是能夠用的。默認地,它輸出到console。想直接寫入文件,使用--reporter-options output=filename.xml
。
Mocha容許自定義第三方的測試報告生成器。瀏覽wiki獲取更多信息。一個例子是TeamCity reporter。
Mocha能夠運行在瀏覽器中。Mocha的每一個釋出版本都會有./mocha.js
和./mocha.css
來在瀏覽器中使用。
下面的方法僅在瀏覽器環境中有效: mocha.allowUncaught()
:若是調用,未捕獲的錯誤不會被error handler處理。
一個典型的設置看起來可能像下面這樣,在載入測試腳本,在onload
中用mocha.run()
運行它們以前,咱們調用mocha.setup('bdd')
來使用BDD風格的接口。
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
<div id="mocha"></div>
<script src="https://cdn.rawgit.com/jquery/jquery/2.1.4/dist/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/Automattic/expect.js/0.3.1/index.js"></script>
<script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
<script>mocha.setup('bdd')</script>
<script src="test.array.js"></script>
<script src="test.object.js"></script>
<script src="test.xhr.js"></script>
<script> mocha.checkLeaks(); mocha.globals(['jQuery']); mocha.run(); </script>
</body>
</html>
複製代碼
瀏覽器中也可使用--grep
功能。在你的URL上添加一個請求參數:?grep=api
。
Mocha的選項能夠經過mocha.setup()
來配置。好比:
// Use "tdd" interface. This is a shortcut to setting the interface;
// any other options must be passed via an object.
mocha.setup('tdd');
// This is equivalent to the above.
mocha.setup({
ui: 'tdd'
});
// Use "tdd" interface, ignore leaks, and force all tests to be asynchronous
mocha.setup({
ui: 'tdd',
ignoreLeaks: true,
asyncOnly: true
});
複製代碼
下面的選項僅在瀏覽器環境有效: noHighlighting
:若是設置爲true
,do not attempt to use syntax highlighting on output test code。
回到服務器,Mocha會試圖加載./test/mocha.opts
做爲Mocha的配置文件。文件是由命令行參數按行拼接起來的。命令行參數也是有優先級的,例如,假定你有下面的mocha.opt
文件:
--require should
--reporter dot
--ui bdd
複製代碼
它會將默認測試報告設置爲dot,加載should
斷言庫,並使用BDD風格的接口。而後你可能會繼續帶參數運行Mocha,這裏是開啓Growl支持,並將測試報告更換爲list:
$ mocha --reporter list --growl
複製代碼
test/
文件夾Mocha默認會全局尋找./test/*.js
和./test/*.coffee
,因此你可能須要將你的測試文件放到./test
文件夾中
下面的編輯器插件package可用:
Mocha的TextMate包包含了可以加速測試編寫的代碼片斷。克隆Mocha repo並運行make tm
來安裝這個包
JetBrains爲它們的IDE套件(IntelliJ IDEA,WebStorm等)提供了一個NodeJS插件,包含了一個Mocha test runner,和一些周邊。
插件名爲NodeJS,而且能夠經過Preference > Plugins來安裝...若是你的許可容許的話。
Wallaby.js是一個持續測試工具,爲JetBrains IDE和Visual Studio中的Mocha提供實時的測試覆蓋率,無論是運行在node.js仍是瀏覽器的項目。
Emacs支持經過第三方插件mocha.el來運行Mocha測試。插件能夠在MELPA上找到,也可經過M-x package-install mocha
來安裝。
真實案例代碼:
運行Mocha自己的測試,你可能須要GUN Make或者其它兼容的環境;Cygwin應該就能夠。
$ cd /path/to/mocha
$ npm install
$ npm test
複製代碼
使用不一樣的測試報告:
$ REPORTER=nyan npm test
複製代碼
除了在Gitter上與咱們交談,也能夠去GitHub上的Mocha Wiki獲取諸如 using spies、mocking和shared behaviours等更多信息。加入Google Group進行討論。查看example/tests.html獲取Mocha運行實例。查看source獲取 JavaScript API。
譯者注:這裏的意思是,只要這個斷言庫在遇到測試不經過時會拋出異常(throws an Error),它就可使用在Mocha中。這意味着即便你不使用任何斷言庫,徹底本身實現測試代碼,只要在遇到測試部不經過時你拋出異常,也是能夠的,不過一般沒有人願意這麼費力不討好 ↩︎
譯者注:在it()函數的第二個參數,也就是it的回調函數中,添加一個參數,這個參數也是一個回調函數,命名隨意,一般都會命名爲done
,而後在異步代碼運行完畢後調用它便可 ↩︎
譯者注:這是爲了避開無窮的回調漩渦 ↩︎
譯者注:這裏指的是省略done()這個回調函數 ↩︎
譯者注:還記得前文提到的done()回調函數麼,在這些鉤子中處理異步代碼與在測試用例中處理異步代碼是同樣的 ↩︎
譯者注:這是指在命令行運行 mocha 命令時帶上 --delay參數,下文的setTimeout僅作演示用,並不是真實的異步操做 ↩︎
譯者注:這裏的意思是,可使用掛起的測試用例來佔個位置,先寫上測試用例,但可能因爲某些緣由,好比被測代碼還未實現,這個測試用例的內容將在稍後編寫,這樣的測試用例既不會pass也不會fail,而是處於pendding狀態 ↩︎
譯者注:這裏指的是嵌套的only()會存在優先級 ↩︎
譯者注:這裏所謂的「什麼也沒作」指的是當測試環境不正確時,測試代碼什麼也沒作,只是簡單的跳過了 ↩︎
譯者注:這裏的「什麼也不作」與前文的「什麼也不作」不是一個意思,這裏的意思是既不寫斷言也不跳過,只是簡單地空在那裏(簡單地空在那裏這個測試的狀態也會是passing) ↩︎
譯者注:這種方式指的是,判斷測試環境是否準本好並使用this.skip()來跳過測試 ↩︎
譯者注:「覆蓋這個值」指的是在嵌套的測試套件或者測試用例中再次經過this.timeout()來進行超時限制從而覆蓋父級套件的設置 ↩︎
譯者注:指的是接口風格 ↩︎
譯者注:這裏指的是編程風格扁平化,即沒有多層嵌套 ↩︎