PHPStorm中如何对nodejs项目进行单元测试详解


Posted in NodeJs onFebruary 28, 2019

安装必要的包

nodejs的单元测试最常用的是使用mocha包。首先确保你本地安装nodejs,之后按照mocha包。

npm install mocha -g

然后还需要安装相关的断言工具,Node.js中常用的断言库有:

  • assert: TDD风格
  • should: BDD风格
  • expect: BDD风格
  • chai: BDD/TDD风格

使用npm install安装这些断言库其中之一即可。

PHPStorm配置nodejs单元测试环境

在PHPStorm中选择菜单:Run -> Edit Configurations,点击右上角添加mocha。

PHPStorm中如何对nodejs项目进行单元测试详解

分别填写下面几项,关于mocha单元测试可以参考官网:https://mochajs.org/

  • Name: 随便一个运行配置的名称,如MochaTest
  • Working directory: 当前项目目录
  • Mocha package: Mocha安装包的目录,node_modules\mocha
  • User interface: 测试类型,这里选择TDD(对应assert库)
  • Test directory: 这一项可以选择测试目录或文件
    • All in directory: 整个目录都进行测试
    • File patterns: 某种模式的文件,可以填正则表达式
    • Test file: 某个特定的测试文件

填写完成并且没有报错后点击OK。

Nodejs进行单元测试

这里我们选择assert库,TDD模式进行单元测试。在上面选定的Test directory目录下新建一个测试文件test.js.

const assert = require('assert');

// 测试Array类型的方法
suite('Array', function() {
 // 测试 indexOf方法
 suite('#indexOf()', function() {
  // 测试用例
  test('should return -1 when not present', function() {
   assert.equal(-1, [1, 2, 3].indexOf(4));
  });
 });
});

点击选择Mocha运行,在PHPStorm下面的输出框中有测试的结果,绿色表示通过,红色表示失败。

PHPStorm中如何对nodejs项目进行单元测试详解

断言库的使用

mocha进行单元测试的时候,除了能够使用assert断言库,只要断言代码中抛出Error,mocha就可以正常工作。

assert库:TDD风格

下面列举assert库中常用的断言函数,详情可参考官网:https://www.npmjs.com/package/assert

  • assert.fail(actual, expected, message, operator)
  • assert(value, message), assert.ok(value, [message])
  • assert.equal(actual, expected, [message])
  • assert.notEqual(actual, expected, [message])
  • assert.deepEqual(actual, expected, [message])
  • assert.notDeepEqual(actual, expected, [message])
  • assert.strictEqual(actual, expected, [message])
  • assert.notStrictEqual(actual, expected, [message])
  • assert.throws(block, [error], [message])
  • assert.doesNotThrow(block, [message])
  • assert.ifError(value)

其中的参数说明如下:

  • value: 实际值
  • actual: 实际值
  • expected: 期望值
  • block: 语句块
  • message: 附加信息

BDD风格should.js断言库

安装方法:npm install should --save-dev,官网地址:https://github.com/shouldjs/should.js

const should = require('should');

const user = {
 name: 'tj'
 , pets: ['tobi', 'loki', 'jane', 'bandit']
};

user.should.have.property('name', 'tj');
user.should.have.property('pets').with.lengthOf(4);

// If the object was created with Object.create(null)
// then it doesn't inherit `Object.prototype`, so it will not have `.should` getter
// so you can do:
should(user).have.property('name', 'tj');

// also you can test in that way for null's
should(null).not.be.ok();

someAsyncTask(foo, function(err, result){
 should.not.exist(err);
 should.exist(result);
 result.bar.should.equal(foo);
});

should库可以使用链式调用,功能非常强大。相关文档参考:http://shouldjs.github.io/

user.should.be.an.instanceOf(Object).and.have.property('name', 'tj');
user.pets.should.be.instanceof(Array).and.have.lengthOf(4);

常用的should断言方法:

无意义谓词,没作用增加可读性:.an, .of, .a, .and, .be, .have, .with, .is, .which

  • should.equal(actual, expected, [message]): 判断是否相等
  • should.notEqual(actual, expected, [message]): 判断是否不相等
  • should.strictEqual(actual, expected, [message]): 判断是否严格相等
  • should.notStrictEqual(actual, expected, [message]): 判断是否严格不相等
  • should.deepEqual(actual, expected, [message]): 判断是否递归相等
  • should.notDeepEqual(actual, expected, [message]): 判断是否递归不想等
  • should.throws(block, [error], [message]): 判断是否抛出异常
  • should.doesNotThrow(block, [message]): 判断是否不抛出异常
  • should.fail(actual, expected, message, operator): 判断是否不等
  • should.ifError(err): 判断是否为错误
  • should.exist(actual, [message]): 判断对象是否存在
  • should.not.exist(actual, [message]): 判断对象是否不存在

另外should还提供了一系列类型判断断言方法:

// bool类型判断
(true).should.be.true();
false.should.not.be.true();

// 数组是否包含
[ 1, 2, 3].should.containDeep([2, 1]);
[ 1, 2, [ 1, 2, 3 ]].should.containDeep([ 1, [ 3, 1 ]]);

// 数字比较
(10).should.not.be.NaN();
NaN.should.be.NaN();
(0).should.be.belowOrEqual(10);
(0).should.be.belowOrEqual(0);
(10).should.be.aboveOrEqual(0);
(10).should.be.aboveOrEqual(10);

// Promise状态判断
// don't forget to handle async nature
(new Promise(function(resolve, reject) { resolve(10); })).should.be.fulfilled();

// test example with mocha it is possible to return promise
it('is async', () => {
 return new Promise(resolve => resolve(10))
  .should.be.fulfilled();
});

// 对象的属性判断
({ a: 10 }).should.have.property('a');
({ a: 10, b: 20 }).should.have.properties({ b: 20 });
[1, 2].should.have.length(2);
({}).should.be.empty();

// 类型检查
[1, 2, 3].should.is.Array();
({}).should.is.Object();

几种常见的测试风格代码举例

BDD

BDD提供的接口有:describe(), context(), it(), specify(), 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(), and teardown():

suite('Array', function() {
 setup(function() {
  // ...
 });

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

QUNIT

和TDD类似,使用suite()和test()标记测试永烈,包含的接口有:before(), after(), beforeEach(), and 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);
});

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

NodeJs 相关文章推荐
Nodejs进程管理模块forever详解
Jun 01 NodeJs
基于NodeJS的前后端分离的思考与实践(四)安全问题解决方案
Sep 26 NodeJs
nodejs中实现路由功能
Dec 29 NodeJs
NodeJS学习笔记之MongoDB模块
Jan 13 NodeJs
NodeJS整合银联网关支付(DEMO)
Nov 09 NodeJs
nodejs构建本地web测试服务器 如何解决访问静态资源问题
Jul 14 NodeJs
NodeJS实现视频转码的示例代码
Nov 18 NodeJs
nodejs超出最大的调用栈错误问题
Dec 27 NodeJs
nodejs基于WS模块实现WebSocket聊天功能的方法
Jan 12 NodeJs
Nodejs Express 通过log4js写日志到Logstash(ELK)
Aug 30 NodeJs
Nodejs让异步变成同步的方法
Mar 02 NodeJs
nodejs实现获取本地文件夹下图片信息功能示例
Jun 22 NodeJs
Nodejs对postgresql基本操作的封装方法
Feb 20 #NodeJs
深入理解nodejs搭建静态服务器(实现命令行)
Feb 05 #NodeJs
Nodejs实现的操作MongoDB数据库功能完整示例
Feb 02 #NodeJs
基于Koa(nodejs框架)对json文件进行增删改查的示例代码
Feb 02 #NodeJs
用Electron写个带界面的nodejs爬虫的实现方法
Jan 29 #NodeJs
NVM安装nodejs的方法实用步骤
Jan 16 #NodeJs
nodeJS进程管理器pm2的使用
Jan 09 #NodeJs
You might like
php中看实例学正则表达式
2006/12/25 PHP
php生成gif动画的方法
2015/11/05 PHP
php倒计时出现-0情况的解决方法
2016/07/28 PHP
Jquery实战_读书笔记2 选择器
2010/01/22 Javascript
Document对象内容集合(比较全)
2010/09/06 Javascript
javascript实现倒计时(精确到秒)
2015/06/26 Javascript
JS实现3D图片旋转展示效果代码
2015/09/22 Javascript
对jQuary选择器的全面总结
2016/06/20 Javascript
完美的js div拖拽实例代码
2016/09/24 Javascript
ionic 3.0+ 项目搭建运行环境的教程
2017/08/09 Javascript
vue使用自定义icon图标的方法
2018/05/14 Javascript
Vue props用法详解(小结)
2018/07/03 Javascript
vue-router beforeEach跳转路由验证用户登录状态
2018/12/26 Javascript
js 计算图片内点个数的示例代码
2019/04/04 Javascript
vue+elementUi图片上传组件使用详解
2019/08/20 Javascript
layui将table转化表单显示的方法(即table.render转为表单展示)
2019/09/24 Javascript
ES5和ES6中类的区别总结
2020/12/21 Javascript
vue实现禁止浏览器记住密码功能的示例代码
2021/02/03 Vue.js
[01:18:33]Secret vs VGJ.S Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
[01:20]PWL开团时刻DAY9——听说潮汐没用?
2020/11/10 DOTA
Python检测一个对象是否为字符串类的方法
2015/05/21 Python
浅谈numpy库的常用基本操作方法
2018/01/09 Python
10招!看骨灰级Pythoner玩转Python的方法
2019/04/15 Python
Python实现京东秒杀功能代码
2019/05/16 Python
Python基于OpenCV实现人脸检测并保存
2019/07/23 Python
python算的上脚本语言吗
2020/06/22 Python
北美领先的牛仔品牌:Buffalo David Bitton
2017/05/22 全球购物
Kidsroom台湾:来自德国的婴儿用品
2017/12/11 全球购物
高级护理实习生自荐信
2013/09/28 职场文书
公司年终奖分配方案
2014/06/16 职场文书
夫妻分居协议书范本(有子女版)
2014/11/01 职场文书
校园安全主题班会
2015/08/12 职场文书
25句企业管理语录:助你迅速打开思路,句句经典!
2020/01/14 职场文书
Pytorch中TensorBoard及torchsummary的使用详解
2021/05/12 Python
教你怎么用Python生成九宫格照片
2021/05/20 Python
CSS 左边固定宽右边自适应的6种方法
2022/05/15 HTML / CSS