抄一个 Node.js 包教不包会 的例子:
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));
}
exports.fibonacci = fibonacci;
简单测试一下:
[dongshaoshuai~/test] ]$node main.js 10
fibonacci(10) is 55
首先全局安装 ava:npm install ava -g
创建测试文件 main.test.js
:
import test from 'ava';
import {fibonacci} from './main.js';
test('main', t => {
// 断言
t.is(fibonacci(10), 55);
});
执行 ava main.test.js
:
[dongshaoshuai~/test] ]$ava main.test.js
1 passed
安装 NYC npm install nyc -g
运行 nyc ava main.test.js
:
[dongshaoshuai~/test] ]$nyc ava main.test.js
1 passed
----------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
test/ | 80 | 83.33 | 100 | 80 | |
main.js | 80 | 83.33 | 100 | 80 | 18,19 |
----------|----------|----------|----------|----------|----------------|
All files | 80 | 83.33 | 100 | 80 | |
----------|----------|----------|----------|----------|----------------|
对 fibonacci 函数的几个要求:
- 当 n === 0 时,返回 0;n === 1时,返回 1
- n > 1 时,返回
fibonacci(n) === fibonacci(n-1) + fibonacci(n-2)
,如fibonacci(10) === 55
- n 也不可小于 0,否则抛错,因为没意义
- n 也不可小于 0,否则抛错,因为没意义
完善测试用例:
import test from 'ava';
import {fibonacci} from './main.js';
test('should equal 0 when n === 0', t => {
t.is(fibonacci(0), 0);
});
test('should equal 1 when n === 1', t => {
t.is(fibonacci(1), 1);
});
test('should equal 55 when n === 10', t => {
t.is(fibonacci(10), 55);
});
test('should throw when n < 0', t => {
t.throws(() => fibonacci(-1), 'n should >= 0');
});
test('should throw when n isnt Number', t => {
t.throws(() => fibonacci('hha'), 'n should be a Number');
});
执行 nyc ava main.test.js
:
[dongshaoshuai~/test/test] ]$nyc ava main.test.js
3 passed
2 failed
1. should throw when n < 0
Maximum call stack size exceeded
Test.fn (main.test.js:17:7)
processEmit [as emit] (/data/home/dongshaoshuai/.nvm/versions/node/v5.3.0/lib/node_modules/nyc/node_modules/signal-exit/index.js:146:32)
processEmit [as emit] (/data/home/dongshaoshuai/.nvm/versions/node/v5.3.0/lib/node_modules/nyc/node_modules/signal-exit/index.js:146:32)
2. should throw when n isnt Number
Maximum call stack size exceeded
Test.fn (main.test.js:21:7)
processEmit [as emit] (/data/home/dongshaoshuai/.nvm/versions/node/v5.3.0/lib/node_modules/nyc/node_modules/signal-exit/index.js:146:32)
processEmit [as emit] (/data/home/dongshaoshuai/.nvm/versions/node/v5.3.0/lib/node_modules/nyc/node_modules/signal-exit/index.js:146:32)
----------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
test/ | 80 | 83.33 | 100 | 80 | |
main.js | 80 | 83.33 | 100 | 80 | 26,27 |
----------|----------|----------|----------|----------|----------------|
All files | 80 | 83.33 | 100 | 80 | |
----------|----------|----------|----------|----------|----------------|
看到最后两个用例没有通过,修改 main.js
:
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 === 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));
}
exports.fibonacci = fibonacci;
重新测试:
[dongshaoshuai~/test/test] ]$nyc ava main.test.js
5 passed
----------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
test/ | 85.71 | 90 | 100 | 85.71 | |
main.js | 85.71 | 90 | 100 | 85.71 | 24,25 |
----------|----------|----------|----------|----------|----------------|
All files | 85.71 | 90 | 100 | 85.71 | |
----------|----------|----------|----------|----------|----------------|
ava --init
会在 package.json 创建测试脚本,修改一下:
"scripts": {
"test": "ava main.test.js"
}
之后可 npm test
来测试。
NYC 在.nyc_ouput文件夹中为每个进程创建一个json的覆盖率文件。
添加生成 html 报告的 npm 脚本:
"scripts": {
"test": "nyc ava main.test.js",
"report": "nyc report --reporter=html"
}
npm run report
会在项目根目录下的 coverage
目录下生成 html 报告。
Travis CI & Coveralls 首先,你需要登录 coveralls.io 并激活你的项目库。 一旦完成,添加 coveralls 到开发依赖库: $ npm install coveralls --save-dev 然后添加下面的代码到你的.travis.yml:
after_success:
- './node_modules/.bin/nyc report --reporter=text-lcov | ./node_modules/.bin/coveralls'
你的覆盖率报告将在你的 Travis 完成后很快地出现在 coveralls 上面。
avajs 本身不带 mock 功能,可以借助 Sinon.JS mock 函数。
mock.js:
var test = require('ava');
var sinon = require('sinon');
var tt = {
f: function () {}
}
test('my test', function(t) {
var m = sinon.mock(tt);
m.expects('f').once();
tt.f();
m.verify();
t.pass();
})
ava mock.js
:
[vagrant@dss /data/test] ]$ava mock.js
1 passed