Mocha 渐进式学习(一)-语法和API

1,177 阅读4分钟

基础概念和简单 API

TDD 模式

TDD(Test Driven Development): 测试驱动开发. 大致来说, 是在 Developer 开发之前,先写test case, 然后再来实现业务逻辑,写完之后再跑一遍测试用例, 看能否通过, 添加新功能, 也是现加测试用例, 然后新功能实现后, 再跑一次所有的测试用例.

接口执行顺序

  • suiteSetup: 所有测试执行前执行一次
  • setup: 每个测试执行前执行
  • test: 具体的测试执行代码
  • teardown: 每个测试执行完后执行一次
  • suiteTeardown: 所有测试执行完后执行一次

Test Case 测试用例结构

  • Setup: 准备好环境和数据
  • Execution: 执行测试
  • Validation: 验证结果
  • Cleanup: 现场恢复

BDD 模式

BDD(Behavior Driven Development):行为驱动开发,BDD 旨在消除 TDD 过程中可能造成的问题,更注重功能本省而非单纯的测试用例运行结果。

主要 API

BDD 主要有两个 api:

  • describe(name,fn):定义一组测试
  • it(name,fn): 定义一项测试
describe('proxy', function() {
    it('proxy data 1', function(done) {
        this.timeout(1000);
        assert.ok(true, 'fail');
    });

    //嵌套
    describe('child1', function() {});

    //只测试某一组
    describe.only('testc1', function() {});

    //跳过某一组测试
    describe.skip('testc1', function() {});
});

onlyskip可以用在describe上, 也可以用在it上.

BDD Hook

在整个测试周期中, mocha 提供了一组 hook:

  • before: 所有测试之前
  • after: 所有测试之后
  • beforeEach: 每个测试之前
  • afterEach: 每个测试之后

hook中的异步处理类似于it.

异步测试

以 BDD 的接口为例, 异步代码的测试,有回调和 Promise 两种方式:

  1. 回调
descibe('Array',function(){
	if('shoule correct',function(done){
		setTimeout(done,1000);
	})
})

如果 done()执行的时候有参数,如 done('错误'), 那么 mocha 判定测试不通过。 你也可以直接传入一个 Error 对象到 done 函数中,如 done(new Error('fail'))

  1. promise
describe('Array', function() {
    it('should correct', function() {
        return Promise.resolve();
    });
});

如果it 函数的返回值是一个promise, 将被是为是一个异步测试。并且根据promisefullfill状态来决定测试是否通过。

箭头函数

mocha 不提倡使用箭头函数, 因为it,describe都是绑定 mocha context 执行的, 才箭头函数中无法获取 mocha context, 会报错.

describe('Array', () => {
    it('shoule correct', done => {
        this.timeout(1000); // can not read property timeout of undefind
    });
});

命令行参数

这里简单的介绍一下常用的命令行参数, 认识即可, 具体使用的时候参考文档是最靠谱的:

  • --reporter,-R: 指定测试报告的格式,可以是tag,spec(默认),dot等等
  • --growl,-G: 将测试结果显示在桌面
  • --watch,-w: 监视指定的测试脚本, 一旦脚本发生变化, 就运行 mocha
  • --bail,-b: 一旦一个测试用例没有通过,就停止执行后面的测试
  • --grep, -g: 指定执行特定的次测试用例
  • --invert, -i: 只运行不符合条件的测试脚本.使用如下:mocha --grep "1 加 1" --invert
  • --compilers: 指定测试脚本的转码器
  • --timeout, -t: 指定每个测试用例最多执行的时间,默认是 2000ms, 用该参数指定超时时间.
  • --slow, -s: 高亮超过指定时间的测试用例,默认是 75ms

可以将命令行参数放在项目test目录下的mocha.opts文件中, 把命令行参数写在里面:

--reporter tap
--recursive
--growl

断言

mocha 没有自己的断言库, 所以可以使用第三方的断言,比如 node 的assert,chai等, 只要程序抛出一个错误, mocha 就会认为其测试不通过。

asset 断言

常用的asset断言函数(node 内置)

  • assert.fail(String|Error): 抛出一个 AssertionError,如果参数是一个 Error,则抛出一个 Error
  • assert.ifError(any): 只要 any, 不等于 undefined|null,就抛出 any
  • assert.ok(value[,message]): 测试 value 是否为 truthy
  • assert.equal(actual,expected[,message]) | assert.notEqual(actual,expected[,message]): 对 actual 和 expected 执行==比较
  • assert.strictEqual(),assert.notStrictEqual: 对 actual 和 expcted 执行===比较
  • assert.deepStrictEqual(),assert.notDeepStrictEqual(): 测试是否深度全等,执行的是===比较。

chai 断言

chai 作为第三方的断言库, 支持 TDD 和 BDD 两种风格的测试, 其中 BDD 的风格有两种:expectshould. 本节不准备全面的介绍所有的 API 接口, 而选取了expect相关的风格接口. expect接口使用构造函数来创建断言对象实例, 而should通过Object.prototype新增方法来实现断言, 不支持IE. 除此之外, expect指向对象, should指向一个函数.

var chai = require('chai'),
    expect = chai.expect,
    should = chai.should();

语言链, 不提供测试能力, 只为了可读性:

to,be,been,is,that,which,and,has,have,with,at,of,same

常用断言链:

  • .not: 否定断言, 不推荐, 尽量使用期待断言, 而非期待断言
  • .deep: 其后的断言深度但不严格相等
  • .own: 其后的断言中的继承属性被忽略.
  • .nested: 其后的断言可以使用./[], 不可与own连用
  • .ordered: 要求顺序
  • .any: 至少有一个
  • .all: 全部包含
  • .lengthOf: 长度匹配
  • .match: 正则匹配
  • .string: 包含所给的字串
  • .keys: 包含所给键
  • .members: 数组成员相同
  • .oneOf: 期待目标数组的成员
  • .change: 断言改变的值
  • .increase: 断言增长的值
  • .decrease: 断言减少的值

参考链接