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 后缀名判断限制代码
Mar 31 NodeJs
NodeJS Web应用监听sock文件实例
Feb 18 NodeJs
nodejs通过phantomjs实现下载网页
May 04 NodeJs
使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室
Aug 21 NodeJs
nodejs修复ipa处理过的png图片
Feb 17 NodeJs
基于nodejs res.end和res.send的区别
May 14 NodeJs
nodejs 生成和导出 word的实例代码
Jul 31 NodeJs
nodejs实现范围请求的实现代码
Oct 12 NodeJs
nodejs中函数的调用实例详解
Oct 31 NodeJs
Nodejs中的require函数的具体使用方法
Apr 02 NodeJs
监控Nodejs的性能实例代码
Jul 02 NodeJs
NodeJS 文件夹拷贝以及删除功能
Sep 03 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
别人整理的服务器变量:$_SERVER
2006/10/20 PHP
php二维码生成以及下载实现
2017/09/28 PHP
PHP实现负载均衡session共享redis缓存操作示例
2018/08/22 PHP
yii框架数据库关联查询操作示例
2019/10/14 PHP
基于jquery的合并table相同单元格的插件(精简版)
2011/04/05 Javascript
JQuery结合CSS操作打印样式的方法
2013/12/24 Javascript
Jquery+Ajax+PHP+MySQL实现分类列表管理(上)
2015/10/28 Javascript
JS表格组件神器bootstrap table详解(强化版)
2016/05/26 Javascript
各式各样的导航条效果css3结合jquery代码实现
2016/09/17 Javascript
javascript字符串对象常用api函数小结(连接,替换,分割,转换等)
2016/09/20 Javascript
让html元素随浏览器的大小自适应垂直居中的实现方法
2016/10/12 Javascript
利用vue+elementUI实现部分引入组件的方法详解
2017/11/22 Javascript
详解webpack4多入口、多页面项目构建案例
2018/05/25 Javascript
Angular中sweetalert弹框的基本使用教程
2018/07/22 Javascript
微信小程序自定义组件封装及父子间组件传值的方法
2018/08/28 Javascript
JS模拟浏览器实现全局搜索功能
2019/09/11 Javascript
详解JavaScript作用域、作用域链和闭包的用法
2020/09/03 Javascript
Python专用方法与迭代机制实例分析
2014/09/15 Python
Python入门篇之面向对象
2014/10/20 Python
Python数据处理numpy.median的实例讲解
2018/04/02 Python
python 求定积分和不定积分示例
2019/11/20 Python
Python开发之基于模板匹配的信用卡数字识别功能
2020/01/13 Python
Jmeter HTTPS接口测试证书导入过程图解
2020/07/22 Python
Html5新标签解释及用法
2012/02/17 HTML / CSS
HTML5触摸事件实现移动端简易进度条的实现方法
2018/05/04 HTML / CSS
Space NK美国站:英国高端美妆护肤商城
2017/05/22 全球购物
澳大利亚婴儿喂养品牌:Cherub Baby
2018/11/01 全球购物
英国DVD和蓝光碟片购买网站:Zoom.co.uk(电影和电视)
2019/09/23 全球购物
教师求职自荐书
2014/06/14 职场文书
祖国在我心中演讲稿(小学生)
2014/09/23 职场文书
公安机关党的群众路线教育实践活动剖析材料
2014/10/10 职场文书
优秀教师事迹材料
2014/12/15 职场文书
民主评议党员个人总结
2015/02/13 职场文书
国庆阅兵观后感
2015/06/15 职场文书
物资采购管理制度
2015/08/06 职场文书
Win11安装升级时提示“该电脑必须支持安全启动”
2022/04/19 数码科技