本次翻译时间为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()来进行超时限制从而覆盖父级套件的设置 ↩︎
译者注:指的是接口风格 ↩︎
译者注:这里指的是编程风格扁平化,即没有多层嵌套 ↩︎