Nodejs测试

1. Mocha

  • js 测试框架,能运行在Node.js 和浏览器中,支持BDD和TDD测试。

  • 灵活(不包括断言和仿真,自己选对应工具),允许使用其他断言库。

  • 社区成熟用的人多,测试各种东西社区都有示例

    本文采用Node内置的assert断言,可自行了解其他断言库)

1.1 安装
# node环境下
npm install -g mocha
复制代码
1.2 脚本编写
  • 测试集(test suite) : describe(name, function(){})

  • 测试用例(test case ):it(name, function(){})

  • 测试的最小单位

  • 专用测试: only

  • 允许只测试指定测试集或案例

  • 跳过测试: skip

  • 允许跳过指定测试集或案例

  • 钩子函数:before, after, beforeEach, afterEach

var assert = require('assert');

//测试集&测试案例
//only 专用测试
describe.only('Array-indexOf', function(){
  it('值不存在时,应返回-1', function(){
    assert.equal(-1, [1,2,3].indexOf(0));
  });
});

//测试集可嵌套使用,测试集包含测试集
//skip 跳过测试
//钩子函数
describe('#String', function(){
  before(function(){
    //测试集前
    //执行一次
  });
  beforeEach(function(){
    //每个测试用例前
    //有几个测试用例,执行几次
  });
  afterEach(function(){
    //单个测试用例后
    //有几个测试用例,执行几次
  });
  after(function(){
    //测试集后
    //执行一次
  });
  
  describe('#indexOf', function(){
    it('值存在时,不应返回-1', function(){
      assert.notEqual(-1, '123'.indexOf('1'));
    });
    it.skip('值不存在时,应返回-1', function(){
    assert.equal(-1, '123'.indexOf('0'));
  });
  });
});
复制代码
1.3 Mocha基本使用
13.1 测试执行
# 执行指定文件
mocha 3.test.js

# 执行默认test目录下测试文件,test子目录下不包括
mocha

#包括test子目录文件
mocha --recursive

#执行指定多个文件
mocha test/{1, 2}.test.js

#shell通配符*
mocha test/*

##也可以使用node通配符
mocha 'test/**/*.@(js|jsx)'
复制代码
13.2 其他命令行参数
  1. --help-h参数,用来查看Mocha的所有命令行参数。
  2. --reporter参数用来指定测试报告的格式,默认是spec格式。
  3. --reporters参数可以显示所有内置的报告格式。
  4. --growl参数,就会将测试结果在桌面显示。
  5. --watch参数用来监视指定的测试脚本。只要测试脚本有变化,就会自动运行Mocha。
  6. --bail参数指定只要有一个测试用例没有通过,就停止执行后面的测试用例。这对持续集成很有用。
  7. --grep参数用于搜索测试用例的名称(即it块的第一个参数),然后只执行匹配的测试用例。
  8. --invert参数表示只运行不符合条件的测试脚本,必须与--grep参数配合使用。
mocha add.test.js --reporter spec
#等同于
mocha add.test.js

#查看tap格式报告
mocha add.test.js --reporter tap

#测试名称中包含"indexOf的测试用例
mocha --grep "indexOf"
#测试名称中不包含"indexOf的测试用例
mocha --grep "indexOf" --invert
复制代码

2. Node.js assert断言

2.1 assert.ok()

assert.ok(value[, message])

  • value 为Truthy时,测试通过

  • value为Falsy时, 抛出错误信息

  • message

    • 无值时或为undefined,抛出默认AssertionError

    • 有值时,AssertionError传入message值

var assert = require('assert');

assert.ok(true); // pass
assert.ok(1); // pass

assert.ok(false); // AssertionError: !!false == true
复制代码
2.2 assert()

assert.ok()的别名。

assert(true); //pass

assert(false); //AssertionError: !!false == true
复制代码
2.3 assert.equal()

assert.equal(actual, expected[, message])

  • actual == expected 时,测试通过
assert.equal(1, 1); //pass
assert.equal(1, '1'); //pass

assert.equal(1, 0); //AssertionError: 1 == 0
复制代码
2.4 assert.notEqual()

assert.notEqual(actual, expected[, message])

  • actual != expected 时,测试通过
assert.notEqual(1, -1); //pass

assert.notEqual(1, '1'); //AssertionError: 1 != '1'
复制代码
2.5 assert.strictEqual()

assert.strictEqual(actual, expected[, message])

  • actual === expected 时,测试通过
assert.strictEqual(1, 1); // pass

assert.strictEqual(1, '1'); //AssertionError: 1 === '1'
复制代码
2.6 assert.notStrictEqual()

assert.notStrictEqual(actual, expected[, message])

  • actual !== expected时,测试通过
assert.notStrictEqual(1, '1'); //pass

assert.notStrictEqual(1, 1); //AssertionError: 1 !== 1
复制代码
2.7 assert.deepEqual()

assert.deepEqual(actual, expected[, message])

  • actual deepEqual expected时,测试通过
assert.deepEqual({a: 1}, {a: 1}); //pass
assert.deepEqual({a: 1}, {a: '1'}); //pass

assert.deepEqual({a: function(){}}, {a: function(){}}); //AssertionError: { a: [Function: a] } deepEqual { a: [Function: a] }
assert.equal({a: 1}, {a: 1}); //AssertionError: { a: 1 } == { a: 1 }
复制代码
2.8 assert.notDeepEqual()

assert.notDeepEqual(actual, expected[, message])

  • actual notDeepEqual expected时,测试通过

assert.notDeepEqual(actual, expected[, message])

assert.notDeepEqual({a: function(){}}, {a: function(){}}); // pass

assert.notDeepEqual({a: 1}, {a: '1'}); //AssertionError: { a: 1 } notDeepEqual { a: '1' }
复制代码
2.9 assert.deepStrictEqual()

assert.deepEqual(actual, expected[, message])

  • actual deepStrictEqual expected时,测试通过
assert.deepStrictEqual({a: 1}, {a: 1}); //pass

assert.deepStrictEqual({a: 1}, {a: '1'}); //AssertionError: { a: 1 } deepStrictEqual { a: '1' }
复制代码
2.10 assert.notDeepStrictEqual()

assert.notDeepEqual(actual, expected[, message])

  • actual deepStrictEqual expected时,测试通过
assert.notDeepStrictEqual({a: '1'}, {a: 1}); //pass
assert.notDeepStrictEqual({a: function(){}}, {a: function(){}}); //pass

assert.notDeepStrictEqual({a: 1}, {a: 1}); //AssertionError: { a: 1 } notDeepStrictEqual { a: 1 }
复制代码
2.11 assert.throws()

assert.throws(fn[, error][, message])

  • fn 抛出一个错误,或者为一个错误
  • error 可捕获错误并对错误进行验证。

assert.throws跟踪错误,所有测试框架都优化过。不要直接用try catch。

var err = function(){xx};

assert.throws(fn, Error); //pass
assert.throws(fn, ReferenceError); //pass

assert.throws(fn, TypeError); //抛出错误

//pass
assert.throws(fn, function(err){
  return err instanceof ReferenceError;
});

//抛出错误
assert.throws(fn, function(err){
  return err instanceof TypeError;
});

复制代码
2.12 assert.fail()

assert.fail([message])

  • 抛出AssertionError错误信息
assert.fail('fail'); //AssertionError: fail

assert.fail(new TypeError('fail')); //AssertionError: TypeError: fail
复制代码

3. Mocha辅助工具

3.1 istanbul
  1. 代码覆盖
  • 行覆盖率(line coverage)

  • 函数执行率(function coverage)

  • 分支覆盖率(brance coverage)

  • 语句覆盖率(statement coverage)

  1. 安装 :npm install -g istanbul

  2. 运行: istanbul cover add.js

  • 可在控制台查看结果

  • 同时会生成一个coverage目录,coverage.json包含覆盖率的原始数据,coverage/lcov-report可以打开覆盖率报告。

3.2 SuperTest
  1. 安装: npm install supertest --save-dev

  2. 使用:【没看明白,用的时候再补充】


4. 测试模式

4.1 TDD

test-driven development 测试驱动开发。

  • 原理:开发功能代码之前,先编写单元测试用例代码,测试代码确定需要写什么产品代码。

  • 基本思想:通过测试推动开发。量化需求分析、设计、质量控制。

4.2 BDD

behavior-driven development 行为驱动开发。

  • 鼓励软件项目中的开发者、QA和非技术人员或商业参与者之间协作。

  • 通过编写行为和规格说明来驱动软件开发。

  • 倡导用简洁的自然语言描述系统行为。

4.3 TDD vs BDD

如例子,二者测试用例最大区别在于措辞,BDD读起来更像是一个句子。

目前大多数基于Nodejs的库或应用都选择了BDD。

var assert = require('assert');

function add(x, y){
  return x + y;
}

//TDD
describe('add', function(){
  it('equals 2 when x =1, y=1', function(){
    assert.equal(2, add(x,y));
  });
});

//BDD
describe('add', function(){
  it('1 plus 1 should be 2', function(){
    assert.equal(2, add(x,y));
  });
});
复制代码

5. 断言库

  1. should.js:BDD风格
  2. expect.js: 支持expect()风格
  3. chai:支持expect(), assert(), should 断言
  4. Node.js集成了assert断言

![image-20181104161236571](../../Library/Application Support/typora-user-images/image-20181104161236571.png)


6. 其他node.js测试框架

  1. Jasmine
  • BDD测试框架。

  • 不依赖于其他js框架。

  • 不需要DOM。

  1. Karma
  • 模拟生产环境。
  • 可以同时在多浏览器测试代码。
  1. Jest
    • 基于Jasmine改进。
    • facebook坐庄。
    • 较多用于React项目。
    • 支持断言和仿真。
  2. Tape
    • 体积最小,只提供最关键的东西
    • 对比其他框架,只提供最底层的 API
  3. AVA
    • 异步,性能好
    • 简约,清晰
    • 快照测试和断言需要三方支持

7. 测试驱动开发意义

强制要求开发时:

  1. 单元尽量解耦,否则单元不可测。
  2. 开发前事先设计接口,再实现细节。
  3. 便于回归和内部代码重构。

Tips:

  • 测试框架&断言库的选取,要结合应用场景。选取性价比最高,最适合需求的。
  • 是否需要进行测试,取决于代码变动频率和公用程度。
  • 业务代码写测试,性价比不高。公用库,比较适合测试驱动开发。
  • 案例:

References:

  1. Nodejs测试:从0到90(理论篇),tralight, 云栖社区
  2. 测试框架 Mocha 实例教程, 阮一峰
  3. 前端测试框架对比(js单元测试框架对比), 晴天_雨天

转载于:https://juejin.im/post/5be053aee51d4515a13fd421

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值