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 的 c++ module 链接到 OpenSSL
Aug 03 NodeJs
nodejs中的fiber(纤程)库详解
Mar 24 NodeJs
详解nodejs 文本操作模块-fs模块(二)
Dec 22 NodeJs
nodejs实现邮件发送服务实例分享
Mar 29 NodeJs
详解nodejs微信公众号开发——4.自动回复各种消息
Apr 11 NodeJs
用Nodejs搭建服务器访问html、css、JS等静态资源文件
Apr 28 NodeJs
详解Windows下安装Nodejs步骤
May 18 NodeJs
Windows下快速搭建NodeJS本地服务器的步骤
Aug 09 NodeJs
NodeJS父进程与子进程资源共享原理与实现方法
Mar 16 NodeJs
nodejs检测因特网是否断开的解决方案
Apr 17 NodeJs
Nodejs 识别图片类型的方法
Aug 15 NodeJs
详解利用nodejs对本地json文件进行增删改查
Sep 20 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的ajax框架xajax入门与试用介绍
2010/12/19 PHP
PHP的mysqli_query参数MYSQLI_STORE_RESULT和MYSQLI_USE_RESULT的区别
2014/09/29 PHP
php实现学生管理系统
2020/03/21 PHP
15款优秀的jQuery导航菜单插件分享
2011/07/19 Javascript
YUI模块开发原理详解
2013/11/18 Javascript
setInterval与clearInterval的使用示例代码
2014/01/28 Javascript
js实现的点击div区域外隐藏div区域
2014/06/30 Javascript
jQuery中:first选择器用法实例
2014/12/30 Javascript
javascript自定义右键弹出菜单实现方法
2015/05/25 Javascript
Angularjs的Controller间通信机制实例分析
2016/11/07 Javascript
原生js实现回复评论功能
2017/01/18 Javascript
JS仿Base.js实现的继承示例
2017/04/07 Javascript
JavaScript事件冒泡与事件捕获实例分析
2018/08/01 Javascript
微信小程序 简易计算器实现代码实例
2019/09/02 Javascript
基于Python如何使用AIML搭建聊天机器人
2016/01/27 Python
微信跳一跳辅助python代码实现
2018/01/05 Python
Python多继承顺序实例分析
2018/05/26 Python
在python中将字符串转为json对象并取值的方法
2018/12/31 Python
详解Python3网络爬虫(二):利用urllib.urlopen向有道翻译发送数据获得翻译结果
2019/05/07 Python
使用python实现回文数的四种方法小结
2019/11/24 Python
tornado+celery的简单使用详解
2019/12/21 Python
浅谈python3打包与拆包在函数的应用详解
2020/05/02 Python
Pytorch 扩展Tensor维度、压缩Tensor维度的方法
2020/09/09 Python
IE9对HTML5中部分属性不支持的原因分析
2014/10/15 HTML / CSS
施华洛世奇澳大利亚官网:SWAROVSKI澳大利亚
2017/01/06 全球购物
美国潜水装备、水肺潜水和浮潜设备商店:Leisure Pro
2018/08/08 全球购物
牧马人澳大利亚官网:Wrangler澳大利亚
2019/10/08 全球购物
亚马逊意大利站点:Amazon.it
2020/12/31 全球购物
解释一下抽象方法和抽象类
2016/08/27 面试题
同步和异步有何异同,在什么情况下分别使用他们?举例说明
2014/02/27 面试题
实体的生命周期
2013/08/31 面试题
MYSQL基础面试题
2012/05/13 面试题
工作态度检讨书
2014/02/11 职场文书
《寓言两则》教学反思
2014/02/27 职场文书
禁烟标语大全
2014/06/11 职场文书
vue+elementui 实现新增和修改共用一个弹框的完整代码
2021/06/08 Vue.js