こちらの記事を読みました。
Mocha, Chai, Sinon を使ったNode.js のテスト自動化 実践編 - Qiita
上記のテストをavaで書き直してみます。
travisでv0.10,v0.12,v4,v5のすべての環境でパスするのを確認しました。
avaについては日本語のドキュメントがあるので、それを確認するといいでしょう。
ava-docs/ja_JP at master · sindresorhus/ava-docs
テスト対象のコードは以下です。
もとのコードから少し変えさせてもらってます。
'use strict';
function calculate(num) {
if (typeof num !== 'number' || isNaN(num)) {
throw new TypeError('Type of numeric is expected.');
}
return Math.floor(num / 2);
}
function read() {
process.openStdin().on('data', function(chunk) {
var param = Number(chunk);
try {
var result = calculate(param);
console.log('result: ' + result);
} catch (e) {
console.log(e.message);
}
});
}
exports.calculate = calculate;
exports.read = read;
環境
$ npm init
$ npm i -D ava
テスト対象のコードをindex.js
、テストファイルをtest.js
とします。
テストコマンドは以下です。
$ ava
詳細
$ ava -v
監視
$ ava -w
実行
内容自体は元コードままです。
avaのテストは並列で走りますが、console.logをスタブする関係で一部直列化しています。
また、avaは内部的にbabelを使っているのでes6で書けます。
import test from 'ava';
import sinon from 'sinon';
import {EventEmitter} from 'events';
import fn from './';
test.beforeEach(t => {
t.context.log = console.log;
sinon.stub(console, 'log');
});
test.afterEach(t => {
console.log = t.context.log;
});
test('return 2 when the value is 4', t => {
t.is(fn.calculate(4), 2);
});
test('return 1 when the value is 3', t => {
t.is(fn.calculate(3), 1);
});
test('throw exceptions when the value are other than numbers', t => {
t.throws(fn.calculate);
t.throws(() => fn.calculate(null), 'Type of numeric is expected.');
t.throws(() => fn.calculate('abc'), / numeric /);
t.throws(() => fn.calculate([]), TypeError, /^Type of numeric /);
});
test.serial('print "result: 4" when the value is 8 that given from the stdin', t => {
const ev = new EventEmitter();
process.openStdin = sinon.stub().returns(ev);
fn.read();
ev.emit('data', '8');
t.is(console.log.callCount, 1);
t.true(console.log.calledWith('result: 4'));
});
test.serial('print "Type of numeric is expected." when the value is not a numeric', t => {
const ev = new EventEmitter();
process.openStdin = sinon.stub().returns(ev);
fn.read();
ev.emit('data', 'abc');
t.is(console.log.callCount, 1);
t.true(console.log.calledWithMatch('Type of numeric is expected.'));
});
比較
chaiのshould記法とexpect記法
// should
divided.calculate(4).should.equal(2);
// expect
expect(divided.calculate(4)).to.equal(2);
ava
t.is(divided.calculate(4), 2);
avaの方が読みやすく簡潔ですね。
また、テストを落としたときのエラーはpower-assertにより非常にわかりやすいです。
1. test › return 1 when the value is 3
t.is(fn.calculate(3), 1)
|
1.5
Test.fn (test.js:15:4)
その他
今回はすべて同期処理のテストでしたが、avaはasyncが使えるので、Promiseによる非同期処理のテストが簡潔に書けます。
import test from 'ava';
function calc(num) {
return new Promise(resolve => {
resolve(num * num);
});
}
test('calc', async t => {
const ans = await calc(10);
t.is(ans, 100);
});