Node.js 6:《测试用例:mocha,should,istanbul》

2018-08-07 15:22 更新

目标

建立一个 lesson6 项目,在其中编写代码。

main.js: 其中有个 fibonacci 函数。fibonacci 的介绍见:http://en.wikipedia.org/wiki/Fibonacci_number 。

此函数的定义为 int fibonacci(int n)

  • 当 n === 0 时,返回 0;n === 1时,返回 1;
  • n > 1 时,返回 fibonacci(n) === fibonacci(n-1) + fibonacci(n-2),如 fibonacci(10) === 55;
  • n 不可大于10,否则抛错,因为 Node.js 的计算性能没那么强。
  • n 也不可小于 0,否则抛错,因为没意义。
  • n 不为数字时,抛错。

test/main.test.js: 对 main 函数进行测试,并使行覆盖率和分支覆盖率都达到 100%。

知识点

  1. 学习使用测试框架 mocha : http://mochajs.org/
  2. 学习使用断言库 should : https://github.com/tj/should.js
  3. 学习使用测试率覆盖工具 istanbul : https://github.com/gotwarlost/istanbul
  4. 简单 Makefile 的编写 : http://blog.csdn.net/haoel/article/details/2886

课程内容

首先,作为一个 Node.js 项目,先执行 npm init 创建 package.json。

其次,建立我们的 main.js 文件,编写 fibonacci 函数。

var fibonacci = function (n) {
  if (n === 0) {
    return 0;
  }
  if (n === 1) {
    return 1;
  }
  return fibonacci(n-1) + fibonacci(n-2);
};

if (require.main === module) {
  // 如果是直接执行 main.js,则进入此处
  // 如果 main.js 被其他文件 require,则此处不会执行。
  var n = Number(process.argv[2]);
  console.log('fibonacci(' + n + ') is', fibonacci(n));
}

OK,这只是个简单的实现。

我们可以执行试试

$ node main.js 10

嗯,结果是 55,符合预期。

接下来我们开始测试驱动开发,现在简单的实现已经完成,那我们就对它进行一下简单测试吧。

我们先得把 main.js 里面的 fibonacci 暴露出来,这个简单。加一句

exports.fibonacci = fibonacci;(要是看不懂这句就去补补 Node.js 的基础知识吧)

就好了。

然后我们在 test/main.test.js 中引用我们的 main.js,并开始一个简单的测试。

// file: test/main.test.js
var main = require('../main');
var should = require('should');

describe('test/main.test.js', function () {
  it('should equal 55 when n === 10', function () {
    main.fibonacci(10).should.equal(55);
  });
});

把测试先跑通,我们再讲这段测试代码的含义。

装个全局的 mocha: $ npm install mocha -g

-g 与 非-g 的区别,就是安装位置的区别,g 是 global 的意思。如果不加的话,则安装 mocha 在你的项目目录下面;如果加了,则这个 mocha 是安装在全局的,如果 mocha 有可执行命令的话,那么这个命令也会自动加入到你系统 $PATH 中的某个地方(在我的系统中,是这里 /Users/alsotang/.nvm/v0.10.29/bin

在 lesson6 目录下,直接执行

$ mocha

输出应如下

那么,代码中的 describe 和 it 是什么意思呢?其实就是 BDD 中的那些意思,把它们当做语法来记就好了。

大家来看看 nodeclub 中,关于 topicController 的测试文件:

https://github.com/cnodejs/nodeclub/blob/master/test/controllers/topic.test.js

这文件的内容没有超出之前课程的范围吧。

describe 中的字符串,用来描述你要测的主体是什么;it 当中,描述具体的 case 内容。

而引入的那个 should 模块,是个断言库。玩过 ruby 的同学应该知道 rspec,rspec 它把测试框架和断言库的事情一起做了,而在 Node.js 中,这两样东西的作用分别是 mocha 和 should 在协作完成。

should 在 js 的 Object “基类”上注入了一个 #should 属性,这个属性中,又有着许许多多的属性可以被访问。

比如测试一个数是不是大于3,则是 (5).should.above(3);测试一个字符串是否有着特定前缀:'foobar'.should.startWith('foo');。should.js API 在:https://github.com/tj/should.js

should.js 如果现在还是 version 3 的话,我倒是推荐大家去看看它的 API 和 源码;现在 should 是 version 4 了,API 丑得很,但为了不掉队,我还是一直用着它。我觉得 expect 麻烦,所以不用 expect,对了,expect 也是一个断言库:https://github.com/LearnBoost/expect.js/ 。

回到正题,还记得我们 fibonacci 函数的几个要求吗?

* 当 n === 0 时,返回 0;n === 1时,返回 1;
* n > 1 时,返回 `fibonacci(n) === fibonacci(n-1) + fibonacci(n-2)`,如 `fibonacci(10) === 55`;
* n 不可大于10,否则抛错,因为 Node.js 的计算性能没那么强。
* n 也不可小于 0,否则抛错,因为没意义。
* n 不为数字时,抛错。

我们用测试用例来描述一下这几个要求,更新后的 main.test.js 如下:

var main = require('../main');
var should = require('should');

describe('test/main.test.js', function () {
  it('should equal 0 when n === 0', function () {
    main.fibonacci(0).should.equal(0);
  });

  it('should equal 1 when n === 1', function () {
    main.fibonacci(1).should.equal(1);
  });

  it('should equal 55 when n === 10', function () {
    main.fibonacci(10).should.equal(55);
  });

  it('should throw when n > 10', function () {
    (function () {
      main.fibonacci(11);
    }).should.throw('n should <= 10');
  });

  it('should throw when n < 0', function () {
    (function () {
      main.fibonacci(-1);
    }).should.throw('n should >= 0');
  });

  it('should throw when n isnt Number', function () {
    (function () {
      main.fibonacci('呵呵');
    }).should.throw('n should be a Number');
  });
});

还是比较清晰的吧?

我们这时候跑一下 $ mocha,会发现后三个 case 都没过。

于是我们更新 fibonacci 的实现:

var fibonacci = function (n) {
  if (typeof n !== 'number') {
    throw new Error('n should be a Number');
  }
  if (n < 0) {
    throw new Error('n should >= 0')
  }
  if (n > 10) {
    throw new Error('n should <= 10');
  }
  if (n === 0) {
    return 0;
  }
  if (n === 1) {
    return 1;
  }

  return fibonacci(n-1) + fibonacci(n-2);
};

再跑一次 $ mocha,就过了。这就是传说中的测试驱动开发:先把要达到的目的都描述清楚,然后让现有的程序跑不过 case,再修补程序,让 case 通过。

安装一个 istanbul : $ npm i istanbul -g

执行 $ istanbul cover _mocha

这会比直接使用 mocha 多一行覆盖率的输出,

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号