NodeJs测试框架Mocha的安装与使用

Mocha是运行在nodejs和浏览器下的JavaScript的单元测试框架,官方文档在,相当的容易上手和好用,单元测试框架其实都差不多,基本都包含下面内容:

用于写测试用例的宏,属性或者函数 断定库, 用于测试是否可以通过 辅助库,如hook库(测试前后调用某些函数或者方法),异常检查(某些函数在某些参数的情况下抛出异常), 输入组合(支持多排列的参数输入组合)等。 支持IDE的集成 下面就按照官方文档的顺序来简明扼要的

安装与初步的使用

在控制台窗口中执行下列命令:

可以写如下代码:

回到控制台:

.

✔ 1 test complete (1ms)

这里mocha会查找当前文件目录下test文件夹下的内容,自动执行。

断定库

这个是判定测试用例是否通过,默认下可以用nodejs的assert库,与此同时,Mocha支持我们使用不同的断定库,现在可以支持下面的断定库,每个断定库的用法有一些差异,自己可以参考相应的文档。

1 should.js() BDD style shown throughout these docs (BDD模式,本文档用的都是这个断定库) 2 better-assert() c-style self-documenting assert()(C-模型下的断定库) 3 expect.js ()expect() style assertions (expect模式的断定库) 4 unexpected() the extensible BDD assertion toolkit 5 chai() expect(),assert() and should style assertions

同步代码

同步代码表示测试的是同步函数,上面的Array相关的例子代码就是。这个比较好理解。

异步代码

只所以有异步代码测试,原因是在nodejs上许多异步函数,如下面的代码中,只有done()函数执行完毕后,该测试用例才算完成

rush:js;"> describe('User',function() { describe('#save()',function() { it('should save without error',function(done) { var user = new User('Luna'); user.saveAsync(function(err) { if (err) throw err; done(); // 只有执行完此函数后,该测试用例算是完成。 }); }); }); });

详解describe和it

上面的实例代码比较简单,那么什么是describe和it呢? 大致上,我们可以看出describe应该是声明了一个TestSuit(测试集合) ,而且测试集合可以嵌套管理,而it声明定义了一个具体的测试用例。 以bdd interface为例,具体的源代码如下:

rush:js;"> /** * Describe a "suite" with the given `title` * and callback `fn` containing nested suites * and/or tests. */ context.describe = context.context = function(title,fn) { var suite = Suite.create(suites[0],title); suite.file = file; suites.unshift(suite); fn.call(suite); suites.shift(); return suite; };

/**

  • Describe a specification or test-case
  • with the given title and callback fn
  • acting as a thunk.
    */

context.it = context.specify = function(title,fn) {
var suite = suites[0];
if (suite.pending) {
fn = null;
}
var test = new Test(title,fn);
test.file = file;
suite.addTest(test);
return test;
};

Hooks(钩子)

实际上这个在写unit test是很常见的功能,就是在执行测试用例,测试用例集合前或者后需要某个回调函数(钩子)。Mocha提供了before(),after(),beforeEach() 和aftetEach(),示例代码如下:

rush:js;"> describe('hooks',function() { before(function() { // runs before all tests in this block // 在执行所有的测试用例前 函数会被调用一次 });

after(function() {
// runs after all tests in this block
// 在执行完所有的测试用例后 函数会被调用一次
});

beforeEach(function() {
// runs before each test in this block
// 在执行每个测试用例前 函数会被调用一次
});

afterEach(function() {
// runs after each test in this block
// 在执行每个测试用例后 函数会被调用一次
});

// test cases
});

hooks还有下列其他用法

Describing Hooks - 可以对钩子函数添加描述,能更好的查看问题 Asynchronous Hooks (异步钩子): 钩子函数可以是同步,也可以是异步的,和测试用例一下,下面是异步钩子的示例代码

rush:js;"> beforeEach(function(done) { // 异步函数 db.clear(function(err) { if (err) return done(err); db.save([tobi,loki,jane],done); }); });

Root-Level Hooks (全局钩子) - 就是在describe外(测试用例集合外)执行,这个一般是在所有的测试用例前或者后执行。 Pending Tests (挂起测试)

就是有一些测试,现在还没有完成,有点类似Todo, 如下面的代码

rush:js;"> describe('Array',function() { // pending test below 暂时不写回调函数 it('should return -1 when the value is not present'); }); });

Exclusive Tests (排它测试)

排它测试就是允许一个测试集合或者测试用例,只有一个被执行,其他都被跳过。如下面测试用例集合:

rush:js;"> describe('Array',function() { describe.only('#indexOf()',function() { // ... }); // 测试集合不会被执行 describe('#ingored()',function() { // ... }); });

下面是对于测试用例:

rush:js;"> describe('Array',function() { it.only('should return -1 unless present',function() { // ... }); // 测试用例不会执行 it('should return the index when present',function() { // ... }); }); });

需要说明的是,对于Hooks(回调函数)会被执行。

Inclusive Tests(包含测试)

与only函数相反,skip函数,将会让mocha系统无视当前的测试用例集合或者测试用例,所有被skip的测试用例将被报告为Pending。 下面是对与测试用例集合的示例代码

rush:js;"> describe('Array',function() { //该测试用例会被ingore掉 describe.skip('#indexOf()',function() { // ... }); // 该测试会被执行 describe('#indexOf()',function() { // ... }); });

下面例子是对具体的测试用例:

rush:js;"> describe('Array',function() { // 测试用例会被ingore掉 it.skip('should return -1 unless present',function() { // ... }); // 测试用例会被执行 it('should return the index when present',function() { // ... }); }); });

Dynamically Generating Tests(动态生成测试用例)

其实这个在很多其他的测试工具,如NUnit也会有,就是将测试用例的参数用一个集合代替,从而生成不同的测试用例。下面是具体的例子:

rush:js;"> var assert = require('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,3],expected: 6},3,4],expected: 10}
];
// 下面就会生成三个不同的测试用例,相当于写了三个it函数的测试用例。
tests.forEach(function(test) {
it('correctly adds ' + test.args.length + ' args',function() {
var res = add.apply(null,test.args);
assert.equal(res,test.expected);
});
});
});

Interfaces(接口)

Mocha的接口系统允许用户用不同风格的函数或者样式写他们的测试用例集合和具体的测试用例,mocha有BDD,TDD,Exports,QUnit和Require 风格的接口。

BDD - 这个是mocha的认样式,我们在本文中的示例代码就是这样的格式。 其提供了describe(),context(),it(),before(),after(),beforeEach(),and afterEach()的函数,示例代码如下:

rush:js;"> describe('Array',function() { before(function() { // ... });

describe('#indexOf()',function() {
context('when not present',function() {
it('should not throw an error',function() {
(function() {
[1,3].indexOf(4);
}).should.not.throw();
});
it('should return -1',function() {
[1,3].indexOf(4).should.equal(-1);
});
});
context('when present',function() {
it('should return the index where the element first appears in the array',3].indexOf(3).should.equal(2);
});
});
});
});

TDD - 提供了 suite(),test(),suiteSetup(),suiteTeardown(),setup(),和 teardown()的函数,其实和BDD风格的接口类似(suite相当于describe,test相当于it),示例代码如下:

rush:js;"> suite('Array',function() { setup(function() { // ... });

suite('#indexOf()',function() {
test('should return -1 when not present',function() {
assert.equal(-1,3].indexOf(4));
});
});
});

Exports - 对象的值都是测试用例集合,函数值都是测试用例。 关键字before,after,beforeEach,and afterEach 需要特别定义。 具体的示例代码如下:

rush:js;"> module.exports = { before: function() { // ... },'Array': { '#indexOf()': { 'should return -1 when not present': function() { [1,3].indexOf(4).should.equal(-1); } } } };

QUnit - 有点像TDD,用suit和test函数,也包含before(),beforeEach()和afterEach(),但是用法稍微有点不一样, 可以参考下面的代码

rush:js;"> function ok(expr,msg) { if (!expr) throw new Error(msg); }

suite('Array');

test('#length',function() {
var arr = [1,3];
ok(arr.length == 3);
});

test('#indexOf()',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 ,it等关键字,这样可以避免全局变量。 如下列代码

rush:js;"> var testCase = require('mocha').describe; var pre = require('mocha').before; var assertions = require('mocha').it; var assert = require('assert');

testCase('Array',function() {
pre(function() {
// ...
});

testCase('#indexOf()',function() {
assertions('should return -1 when not present',function() {
assert.equal([1,3].indexOf(4),-1);
});
});
});

上述认的接口是BDD,如果想使用其他的接口,可以使用下面的命令行:

mocha -ui 接口(TDD|Exports|QUnit...)

Reporters (测试报告/结果样式)

Mocha 支持不同格式的测试结果暂时,其支持 Spec, Dot Matrix,Nyan,TAP…等等,认的样式为Spec,如果需要其他的样式,可以用下列命令行实现:

mocha --reporter 具体的样式(Dot Matrix|TAP|Nyan...)

Editor Plugins

mocha 能很好的集成到TextMate,Wallaby.js,JetBrains(IntelliJ IDEA,WebStorm) 中,这里就用WebStorm作为例子。 JetBrains提供了NodeJS的plugin让我们很好的使用mocha和nodeJs。 添加mocha 的相关的菜单,具体配置过程可以参考nofollow" href="https://www.jetbrains.com/webstorm/help/running-mocha-unit-tests.html">https://www.jetbrains.com/webstorm/help/running-mocha-unit-tests.html

这里就可以直接在WebStorm中运行,调试mocha的测试用例了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要介绍“基于nodejs的ssh2怎么实现自动化部署”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“基于nodejs...
本文小编为大家详细介绍“nodejs怎么实现目录不存在自动创建”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs怎么实现目录不存在自动创建”文章能帮助大...
这篇“如何把nodejs数据传到前端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这...
本文小编为大家详细介绍“nodejs如何实现定时删除文件”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs如何实现定时删除文件”文章能帮助大家解决疑惑...
这篇文章主要讲解了“nodejs安装模块卡住不动怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来...
今天小编给大家分享一下如何检测nodejs有没有安装成功的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文...
本篇内容主要讲解“怎么安装Node.js的旧版本”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎...
这篇“node中的Express框架怎么安装使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家...
这篇文章主要介绍“nodejs如何实现搜索引擎”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“nodejs如何实现搜索引擎...
这篇文章主要介绍“nodejs中间层如何设置”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“nodejs中间层如何设置”文...
这篇文章主要介绍“nodejs多线程怎么实现”,在日常操作中,相信很多人在nodejs多线程怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
这篇文章主要讲解了“nodejs怎么分布式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“nodejs怎么分布式”...
本篇内容介绍了“nodejs字符串怎么转换为数组”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情...
这篇文章主要介绍了nodejs如何运行在php服务器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇nodejs如何运行在php服务器文章都...
本篇内容主要讲解“nodejs单线程如何处理事件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“nodejs单线程如何...
这篇文章主要介绍“nodejs怎么安装ws模块”,在日常操作中,相信很多人在nodejs怎么安装ws模块问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
本篇内容介绍了“怎么打包nodejs代码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!
本文小编为大家详细介绍“nodejs接收到的汉字乱码怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs接收到的汉字乱码怎么解决”文章能帮助大家解...
这篇“nodejs怎么同步删除文件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇...
今天小编给大家分享一下nodejs怎么设置淘宝镜像的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希