テストフレームワーク mocha
JavaScript Advent Calendar 2011 (Node.js/WebSocketsコース)3日目のhokacchaです。Node.jsのテストフレームワーク、mochaについて書きます。
mochaはTJが新しく作り始めているテストフレームワークです。ドキュメントを見ればできることは大体書いてありますので、ドキュメントを元にどういうことができるのかを解説していきます。現時点でのバージョンは0.2.0です。
http://visionmedia.github.com/mocha/
shouldについて
まずmochaでどういうことができるかの前にshouldについて解説しておきます。mochaのドキュメントには特に説明もなくshouldが使われていて、shouldでどういうことができるかわかってないと、ドキュメントを読んだときにmochaの機能なのかshouldの機能なのかがわかりにくくなるからです。
https://github.com/visionmedia/should.js
shouldは一言でいうとassertの拡張です。なので基本的にはテストフレームワークと組み合わせて使うことになります。例えばこんな書き方ができるようになります。
var should = require('should'); var hoge = 'fuga'; var point = { x: 10, y: 20 }; hoge.should.equal('fuga'); point.should.have.property('x', 10); point.should.have.property('y', 20); point.should.not.have.property('z');
見てわかるとおり、shouldはObject.prototypeを拡張します。
またrequire('should')で返ってくるオブジェクトはassertに一部の機能を追加したものなので、このように書くことも可能です。
var should = require('should'); var hoge = 'fuga'; var point = { x: 10, y: 20 }; should.equal(hoge, 'fuga'); should.equal(point.x, 10); should.equal(point.y, 20); should.not.exist(point.z);
これがshouldの基本的な機能です。他にも色々メソッドとかがあるので詳しくはドキュメントを読んでみるといいと思います。
mochaの概要
ここから本題。mochaについての話しです。mocha自体にはアサーションの機能はなく、標準のassertやshouldなどを使ってうまいことテストを書けて、結果の出力とかも色々やってくれるのがmochaの役割です。まずインストールしましょう
$ npm install -g mocha
インストールしたらmochaコマンドが使えるようになるので早速テストを書いてみます。
// test1.js var assert = require('assert'); describe('mochaのテスト', function() { it('1 + 1は2になること', function() { assert.equal(1 + 1, 2); }); });
$ mocha test1.js mochaのテスト - 1 + 1は2になること - tests complete (3ms)
実行できました。describeとかit辺りがmochaの機能です。テスト自体はassertで行っています。
非同期のテストも当然サポートしています。
// test2.js var assert = require('assert'); describe('mochaのテスト', function() { it('1秒待つこと', function(done) { setTimeout(function() { assert.ok(true); done(); }, 1000); }); it('1 + 1は2になること', function() { assert.equal(1 + 1, 2); }); });
$ mocha test2.js mochaのテスト - 1秒待つこと (1002ms) - 1 + 1は2になること - 2 tests complete (1006ms)
doneが呼ばれるまで次のテストを待ちます。
選べるインターフェース
mochaの特徴の一つとして、インターフェースにTDD、BDD、exportsを選べるというのがあります。さっきのコードをTDDインターフェースで書いた場合こうなります。
// test3.js var assert = require('assert'); suite('mochaのテスト', function() { test('1 + 1は2になること', function() { assert.equal(1 + 1, 2); }); });
見てわかる通り、describeがsuite、itがtestとなっているだけです。実際に内部のコードを見ても名前が違うだけでやってることは全く同じです。これを実行するにはコマンドオプションでインターフェースにtddを指定する必要があります。
$ mocha --ui tdd test3.js
exportsもほとんど同じです。
// test4.js var assert = require('assert'); module.exports = { 'mochaのテスト': { '1 + 1は2になること': function() { assert.equal(1 + 1, 2); } } };
実行時のインターフェースはexportsを指定します。
$ mocha --ui exports test4.js
デフォルトのインターフェースはBDDなので何も指定しない場合はBDDとなります。
before、afterフック
テストの最初や最後に処理を挟みたいことはよくあります。mochaではこんな感じで書きます。
var assert = require('assert'); describe('mochaのテスト', function() { before(function(done) { // テストが始まる前の処理 done(); }); after(function(done) { // テストが終わった後の処理 done(); }); beforeEach(function(done) { // 各テストごとの始まる前の処理 done(); }); afterEach(function(done) { // 各テストごとの終わった後の処理 done(); }); it('1 + 1は2になること', function() { assert.equal(1 + 1, 2); }); });
特にdescribeごとのフック(before, after)とitごとのフック(beforeEach, afterEach)が分かれているのはかなりいいですね。
また、TDDインターフェースでは、before→suiteSetup、after→suiteTeardown、beforeEach→setup、afterEach→teardownとなるみたいです(suiteSetupとsuiteTeardownはアンドキュメントだけど単なる書き忘れな気がする)
様々なレポーター
mochaではレポーターもデフォルトで様々なものが用意されています。レポーターってのは出力形式のことです。コマンドラインオプションで様々なレポーターを指定できます。
$ mocha --reporter dot test.js
その他の便利機能
mochaはその他にも便利な機能が色々あります。
require
- rオプションでデフォルトでrequireするモジュールを指定できます。
$ mocha -r should test.js
ただ、例えばこれだとshouldをrequireはするけど、
require('should');
しただけになります。
shouldはObject.prototypeを拡張するので、その拡張した機能は使えるんですけど、require('should')で返ってくるオブジェクトを使うことができません。should自体をこんな感じで使いたいこともあるので、結局ファイルごとに書いたほうがいい気もします。
var should = require('should'); should.not.exist(err);
テストファイルの省略
mochaはテストの対象ファイルの指定を省略するとデフォルトではtest/*.jsを探してテストします。なのでそのようなディレクトリ構成になっていればこれだけでテストできます。
$ mocha
閾値の設定
mochaはテストにかかる時間を計測してくれて、設定された閾値より時間がかかったテストを警告してくれます。レポーターをデフォルト(dot)にしてる場合だとドットが黄色くなるのが警告です。あとspceレポーターとかで時間のところが赤くなってるのもこれです。この閾値のデフォルトは75msで、sオプションで指定できます。
$ mocha -s 1000 test.js
mocha.opts
mochaには様々なオプションがあっていちいち指定するのが面倒な場合、test/mocha.optsというファイルに設定を書いておけば自動で設定を読んでくれるという便利機能があります。
mocha.opts.はこんな感じで書きます。
--ui bdd --reporter spec --timeout 5000
クライアントサイドサポート
mochaはクライアントサイドでの実行もサポートしています。が、これについてはフレームワークコースのほうで書こうと思います。こうご期待。