杨丞琳短发照片-NodeJs测试框架Mocha的安装与使用
函数
石景数学网
函数
2021-09-08

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

辅助库,如hook库(测试前后调用某些函数或者方法),异常检查(某些函数在某些参数的情况下抛出异常), 输入组合(支持多排列的参数输入组合)等。

$ npm install -g mocha $ mkdir test $ $EDITOR test/test.js

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)); }); }); });

$ mocha . ✔ 1 test complete (1ms)

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

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

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

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

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应该是声明了一个TestSuit(测试杨丞琳短发照片) ,而且测试杨丞琳短发照片可以嵌套管理,而it声明定义了一个具体的杨丞琳短发照片。 以bdd interface为例,具体的源代码如下:

/** * 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; };

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

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 });

Describing Hooks - 可以对钩子函数添加描述,能更好的查看问题

Asynchronous Hooks (异步钩子): 钩子函数可以是同步,也可以是异步的,和杨丞琳短发照片一下,下面是异步钩子的示例代码:

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

Root-Level Hooks (全局钩子) - 就是在describe外(杨丞琳短发照片杨丞琳短发照片外)执行,这个一般是在所有的杨丞琳短发照片前或者后执行。

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

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

排它测试就是允许一个测试杨丞琳短发照片或者杨丞琳短发照片,只有一个被执行,其他都被跳过。如下面杨丞琳短发照片杨丞琳短发照片:

describe('Array', function() { describe.only('#indexOf()', function() { // ... }); // 测试杨丞琳短发照片不会被执行 describe('#ingored()', function() { // ... }); });

describe('Array', function() { describe('#indexOf()', function() { it.only('should return -1 unless present', function() { // ... }); // 杨丞琳短发照片不会执行 it('should return the index when present', function() { // ... }); }); });

与only函数相反,skip函数,将会让mocha系统无视当前的杨丞琳短发照片杨丞琳短发照片或者杨丞琳短发照片,所有被skip的杨丞琳短发照片将被报告为Pending。

describe('Array', function() { //该杨丞琳短发照片会被ingore掉 describe.skip('#indexOf()', function() { // ... }); // 该测试会被执行 describe('#indexOf()', function() { // ... }); });

describe('Array', function() { describe('#indexOf()', function() { // 杨丞琳短发照片会被ingore掉 it.skip('should return -1 unless present', function() { // ... }); // 杨丞琳短发照片会被执行 it('should return the index when present', function() { // ... }); }); });

Dynamically Generating Tests(动态生成杨丞琳短发照片)

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

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, 2, 3], expected: 6}, {args: [1, 2, 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); }); }); });

Mocha的接口系统允许用户用不同风格的函数或者样式写他们的杨丞琳短发照片杨丞琳短发照片和具体的杨丞琳短发照片,mocha有BDD,TDD,Exports,QUnit和Require 风格的接口。

BDD - 这个是mocha的默认样式,我们在本文中的示例代码就是这样的格式。

其提供了describe(), context(), it(), before(), after(), beforeEach(), and afterEach()的函数,示例代码如下:

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()的函数,其实和BDD风格的接口类似(suite相当于describe,test相当于it),示例代码如下:

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 - 对象的值都是杨丞琳短发照片杨丞琳短发照片,函数值都是杨丞琳短发照片。 关键字before, after, beforeEach, and afterEach 需要特别定义。

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

QUnit - 有点像TDD,用suit和test函数,也包含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 ,it等关键字,这样可以避免全局变量。

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,2,3].indexOf(4), -1); }); }); });

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

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

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

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

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

这里就可以直接在WebStorm中运行,调试mocha的杨丞琳短发照片了。