Node.js 用Mocha+Chai做单元测试 入门

昨天是六一儿童节(发布的时候已经是前天了= =),给自己放了一天假,然后晚上开始看自动测试的问题。

单元测试是每个程序员都应该自测的部分(《构建之法》中说:单元测试应该由最熟悉程序的人来写——也就是些这段代码的程序员)传统的测试机械化程度太高,肉眼看也是累得不行,此外,代码覆盖率是一个很重要的考察点,人工测试在计算上或称最大难题。

基本概念

当然在此之前,先来科普一些基本概念,也就是单元测试的分类:TDDBDD

TDD

TDD(Test-Driven Development),也就是测试驱动开发,这意味着开发者先写测试样例,然后根据测试样例去实现它,当实现完成之后,他会发现所有的测试样例都是通过了的。

流程图如下:

TTD_flow.png

BDD

BDD(Behavior-Driven Development),行为驱动测试,他看着和TDD很像,但是和TDD又有所不同(当然写出来的测试代码本身其实是一样的)。

它意味着我们先进行代码的编写,然后根据我们代码所要达到的效果或者描述的事实去撰写测试代码,测试是否如我们预想的那样工作。

TDD 与 BDD的区别

在程序上,他们几乎没有区别,唯一的区别可能是修饰性描述,TDD强调将会实现的效果,可能是一句陈述句如:1+1等于2,而BDD强调结果是否正确,是否合乎预期,这句描述可能就会变成:1+1是否等于2。

当然,由于单元测试是程序员的自测流程,也谈不上哪个更好或者更差,选择自己喜欢的就可以了,在我看来BDD可能更符合我的口味,TDD并不一定能覆盖所有情况(因为我不一定考虑完全),这个时候之后根据实现慢慢调整我的测试样例可能更适合我。

另一方面,TDD有点像一份设计文档,而BDD像是之后的公开使用说明书。

如果你还想了解更多,可以见The Difference Between TDD and BDD

Mocha

了解完了基本概念,接下我们来使用工具。

Mocha是一个基于node.js和浏览器的集合各种特性的Javascript测试框架,并且可以让异步测试也变的简单和有趣。Mocha的测试是连续的,在正确的测试条件中遇到未捕获的异常时,会给出灵活且准确的报告。

Mocha是一个框架,具体还得靠断言库,断言库我们之后再介绍。

官方地址:http://mochajs.org/#getting-started

按照我的学习习惯,在使用前先跑一下Demo,扫一下官方的手册功能大致有哪些,方便日后查阅。

在此我们用官方样例为例(官方使用全局安装):

npm install -g mocha
mkdir test
$EDITOR test/test.js

之后我们使用后文即将提到的Chai库(这里另外也可以看出,describe是可以嵌套的):

var assert = require('chai').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(5));
      assert.equal(-1, [1,2,3].indexOf(0));
    });
  });
});

然后在Terminal运行mocha,可以看到运行结果(当然由于这里我们没有安装chai的库,所以无法顺利执行,之后我们就来说说Chai。

Chai

Chai是一个开源断言库,前端或者后端均可使用,因此学习Mocha+Chai这对组合还是很划得来的。

前端测试方式我们之后再说,先从简单的Node.js下手。

Chai官方网址:http://chaijs.com

npm install chai

在执行完毕之后,上文的样例就可以运行了,我们也能看到正确的结果,如果错误,就会抛出断言异常。

Chai提供多种语句,Expect/Should是BDD风格,而Assert是TDD风格,这个主要是风格有些语法差异,使用Should有些额外的注意事项,所以昨天后来我使用了BDD风格的Expect

Expect的风格可以看下官方文档:

var expect = require('chai').expect
  , foo = 'bar'
  , beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };

expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.length(3);
expect(beverages).to.have.property('tea').with.length(3);

var answer = 43;

// AssertionError: expected 43 to equal 42.
expect(answer).to.equal(42);

// AssertionError: topic [answer]: expected 43 to equal 42.
expect(answer, 'topic [answer]').to.equal(42);

我们可以看到结构是expect(待测试数据).to.action(断言值)

具体的action可见:http://chaijs.com/api/bdd/

之后根据具体测试情况选择需要的测试Chain就行了。

代码覆盖报告

衡量单元测试,有一些很重要的参数,我们当然不至于去人工计算,istanbul库会帮我们做到这一点。

官方地址:https://github.com/gotwarlost/istanbul

在github也有相关介绍,这里简单说一下,执行的方法就是:istanbul cover _mocha,然后会执行mocha并且生成报告。

浏览器测试

mocha支持前端测试,结合chai即可使用。

mocha init

接下来引入chai的js文件之后再下面添加上相应测试用例的代码即可(使用方法和前文一致)

之后访问即可。

当然如果使用phantomjs的话效果会更好,这里看这篇文章就差不多了:

《浏览器端测试:mocha,chai,phantomjs》

需要发HTTP请求的测试情况

在测试网站时会有这个需求,这个时候superagent的姐妹supertest可以满足我们,还没有使用过,不过大致可以一看:

《测试用例:supertest》

参考链接

Nodejs单元测试小结

《测试用例:mocha,should,istanbul》

植入部分

如果您觉得文章不错,可以通过赞助支持我。

如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。

标签: 使用, node.js

添加新评论