搬运-测试

Node.js下常用的测试框架mocha、should和一些基本测试方法

概念

1.单元测试
2.集成测试
3.系统测试
4.性能测试
5.benchmarking
6.行为驱动开发(BDD)

框架流程

1.测试框架Mocha
2.断言库should.js
3.Web测试库supertest
4.基准库benchmark

实践

npm install mocha -g
npm install should --save-dev
npm install supertest --save-dev
npm install benchmark --save-dev
mkdir test
code test/test.js

简单例子

使用官方提供的例子,验证数组的indexOf方法越界后是否返回-1,使用了Node.js自带的断言模块assert:

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(4));
    })
  })
})
  • describe(),传进去的字符串可用来描述要测试的主体是什么,可以嵌套,这里要测试的主体就是 Array,indexOf 方法是其中的一个子描述
  • it(),描述具体的case内容,里面包含断言的使用

执行后的输出:

$ mocha test.js 


  Array
    #indexOf()
      ✓ should return -1 when the value is not present


  1 passing (3ms)

修改 assert.equal(-1, [1,2,3].indexOf(4)); 中的值为 0,再执行,得错误断言:

$ mocha test.js 


  Array
    #indexOf()
      1) should return -1 when the value is not present


  0 passing (6ms)
  1 failing

  1) Array
       #indexOf()
         should return -1 when the value is not present:

      AssertionError [ERR_ASSERTION]: 0 == -1
      + expected - actual

      -0
      +-1
      
      at Context.<anonymous> (test.js:5:14)
      at processImmediate (internal/timers.js:461:21)

异步回调测试

写异步测试案例时只需在 it() 中添加一个回调函数(通常是done)

在上面的简单例子基础上,加入延时执行:

var assert = require('assert');
var async = function (callback) {
  setTimeout(function(){
    callback(assert.equal(-1, [1,2,3].indexOf(4)));
  })
};
describe('Array', function(){
  describe('#indexOf()', function(){
    it('should return -1 when the value is not present', function(done) {
      async(function (result) {
        done(result);
      })
    })
  })
})

Promise测试

mocha支持直接返回Promise,执行resolve测试成功,执行reject测试失败

var assert = require('assert');
var promise = new Promise(function(resolve, reject){
  const result = [1,2,3].indexOf(4)
  if(result == -1){
    resolve(true)
  }
  else {
    reject(false)
  }
})
describe('Array', function(){
  describe('#indexOf()', function(){
    it('should return -1 when the value is not present', function(){
      return promise
    })
  })
})

should.js使用

上面的例子如果用于判断复杂情况,可能需要写很多代码。使用should库可以为对象加上更多方法,而不用自己来实现和判断true和false了。

比如可以判断一个对象是否有这个属性,判断类型是否为字符串或数组。

var assert = require('assert');
var should = require('should');
describe('Should', function(){
  it('should have property a ', function(){
    ({ a: 10 }).should.have.ownProperty('a');
  })
})

should支持Promise,可以判断Promise的结果:

var should = require('should');
describe('Should', function(){
  it('should return 10 ', function(){
    return new Promise((resolve, reject) => resolve(10)).should.be.finally.equal(10);
  })
});

Web接口测试

supertest可以直接调用superagent的接口,除此之外还新增了expect接口,可以验证status、header和body,以及在end函数里直接处理返回的数据。

var request = require('supertest');
var should = require('should');
describe('Accout', function(){
  it('Opening account with password: password. Expecting success', function(done){
    request('http://127.0.0.1:7000').post('/accounts/open')
      .set('Accept', 'application/json')
      .send({
        secret: 'password'
      })
      .expect('Content-Type', /json/)
      .expect(200)
      .end(function(err,res){
        if (err) done(err);
        res.body.should.have.property('success', true);
        res.body.should.have.property('account').which.is.Object();
        res.body.account.address.should.equal('1231414221412414');
        res.body.account.publicKey.should.equal('faffasfa1f1414faaffafsfaf');
        done();
      })
  })
})

可通过supertest设置请求路径和参数,对返回的response的status进行判断,并且直接通过end函数处理返回的内容,通过刚才的should库对body的属性进行检验,最后调用done结束。

性能测试

可以使用Node.js自带的console.time输出耗费时间,但如果有比较性的测试,比如需要知道哪个方案运行得更快,就需要benchmark库了:

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;
// add tests
suite.add('RegExp#test', function(){
  /o/.test('Hello World!');
})
.add('String#indexOf', function(){
  'Hello World!'.indexOf('o') > -1;
})
// add listeners
.on('cycle', function(event){
  console.log(String(event.target));
})
.on('complete', function(){
  console.log('Fastest is ' + this.filter('fastest').map('name'));
})
// run async
.run({ 'async': true });

结果:

$ node test.js 
RegExp#test x 41,639,102 ops/sec ±1.62% (89 runs sampled)
String#indexOf x 731,668,178 ops/sec ±1.09% (87 runs sampled)
Fastest is String#indexOf

该例分别使用正则和查找索引来判断一个字符串是否含有“o”,其中,ops/sec测试结果显示的是每秒钟执行测试代码的次数(ops/sec),数值越大越好,同时还会显示测试过程中的统计误差。

posted @ 2021-04-28 16:37  汪淼焱  阅读(74)  评论(0编辑  收藏  举报