javascriptでテスト駆動開発 Mocha+expect.js+testem【前編】
JavaScriptのテストをするツール達
テスト駆動するときに必要なツールが2つあります。
- テストフレームワーク
- テストランナー
テストフレームワーク
いわゆるxUnit系のツールがこれにあたります。
JavaScriptでの有名ドコロは下記のスライドが参考になります。
JS開発におけるTDDと自動テストツール利用の勘所
私はまだ2つしか使ったことがありません。
- Jasmine http://pivotal.github.io/jasmine/
- Mocha Mocha - the fun, simple, flexible JavaScript test framework
どちらもBDDライクな書き方で好きです。
特にMocha(モカと読みます)の方ですが、単体では使わず
should.jsやexpect.jsなどのアサーションライブラリと組み合わせて使います。
これはmocha単体のアサーションがないためです。
JasmineだとSinon.jsをセットでよく使います。
テストランナー
テストだけするなら必要ありませんが、テスト駆動をするなら必須です。
テスト駆動のフローは以下の通りになります。
- テストを書く
- テストが失敗することを確認する(REDを確認)
- 実装する
- テストを走らせテストが通ることを確認する(GREENを確認)
- リファクタリングする
テストランナーを使うと2と3の確認作業が楽になります。
テストの実行をテストランナーがしてくれるので、開発者はその結果を確認するだけで良くなります。
私が知っているテストランナーは3つしかありません・・・(本当はもっとあるはず)
- Testem https://github.com/airportyh/testem
- Karma(Testacular) http://karma-runner.github.io/
- Grunt.js http://gruntjs.com/
Testem
ググってみるとたくさん紹介記事があります。
実際に導入も簡単で、特に悩むことはないと思います。
- 特徴
- ファイルの更新を検出して自動でテストを走らせる
- 複数のブラウザを起動してテスト結果を表示できる
- 事前処理、事後処理を記述できる(coffeeの事前コンパイルとか)
Karma(Testacular)
以前はTestacularという名前でしたがKarmaに変わりました。
比較的新しいランナーで、Google製です。
- 特徴
- Testemとほぼ同等
- Require.jsを用いたテストに対応(Testemよりシンプル)
Grunt.js
Grunt.jsはJavaScriptのテストランナーではありませんが、
テストランナーとしても使えるので紹介だけ。
本当はGruntには違うことを任せて、JavaScriptのテストランナーとしては
使わないことが多いです。
- 特徴
- watchに指定したファイルに更新があればテストを実行する(というタスクを書ける)
- タスクを作って自動コンパイルが得意(coffee, sass, less, stylus, jade, minify, concat, etc..)
- Jenkinsと良い感じに連携できる
mocha + expect.js + Testem でnode.jsのテストする
今回はサーバーサイドのテストをしたいので、出力は全てターミナル上に表示するイメージで環境構築します。
テスト環境の構築
まずmocha, expect.js, testemをインストールします。
$ npm install -g mocha // グローバルにインストール ... $ npm install expect.js --save-dev ... $ npm install -g testem ...
mochaコマンド、testemコマンドが実行できることを確認しておきます。
$ mocha --version 1.9.0 $ testem --version 0.2.94
テストケースを作る
とりあえずテスト対象のファイルと、テストコードを作成します。
$ mkdir lib // テスト対象コードを置くディレクトリ作成 $ touch lib/calc.js $ mkdir test // テストコードを置くディレクトリ作成 $ touch test/calc.test.js
// lib/calc.js // 足し算 exports.add = function(a, b){ return a + b; }
// test/calc.test.js var expect = require('expect.js'); var calc = require('../lib/calc.js'); describe('add', function(){ it('1と1を与えたら2を返す', function(){ var result = calc.add(1, 1); expect(result).to.be(2); }); });
mochaコマンドでテストが実行できることを確認してください。
$ mocha -R spec add ✓ 1と1を与えたら2を返す 1 test complete (9 ms)
mochaコマンドでテストを作れているのを確認できました。
次はこれをtestemに実行させます。
プロジェクトのルート直下にtestem.jsonを作ります。
{ "framework": "mocha", "src_files": [ "lib/*.js", "test/*.test.js" ], "launchers": { "Mocha": { "command": "mocha test/*.test.js -R tap", "protocol": "tap" } }, "launch_in_dev": [ "Mocha" ] }
testemを実行します。
testemを実行すると、ターミナルの画面を占有するので、
新しいターミナルウインドウを立ちあげて実行するのがおすすめです。
$ testem
テストが実行されたと思います。
これでファイルを編集した瞬間、testemがテストを走らせるので
バグに気づきやすくなります。
終わりに
calcというファイルを作っておきながら足し算しか作ってません。
それにこのadd関数はたくさんのバグを含んでいます。
また、今回はサーバーサイドのコードを対象としましたが、
フロント特有のテストの仕方があったりします。
というわけで、次回に続きます。