ブラウザ用に書かれた mocha のテストを Node.js で動作させる mocha-ci-driver を作ってみました

JavaScript のテストを作成する際、動作環境を意識したコードを書くことを手間に感じる方は多いかと思います。

そこで今回は、ブラウザ用に作成した JavaScript のテストコードを、 Node.js を利用した CI 環境でも同じように動作させることができるツールとして、 mocha-ci-driver を作ってみたのでご紹介したいと思います。


* ブラウザでのテスト

本来、ブラウザ用に書かれたテストは基本的にはブラウザでしか動作しません。
受け入れレベルのテストを selenium などを利用して動作させるというのはよくある手段ですが、モデルのみのテストだとなかなかそうもいきません。
そのため、JavaScript のテストをすべて CI に組み込んで動作させることは困難かと思います。

ひとつのアプローチとして、ブラウザでもサーバ(今回は Node.js を対象としています)でも動作するようなコードに書き換えるというのも一つの手段かもしれません。
ロジックだけのモデル層のテストなら互換性を考慮するのも可能でしょう。

(function(global) {
  // code
})(
  'undefined' === typeof exports ?
    window :
    module.exports
);

ただ、外部のライブラリや DOM に依存している部分についてはなかなか素直にはいきません。
例えば、 underscore や jQuery を利用していたら、その部分をブラウザ/サーバ用に差し替えるようなコードが必要になってくるでしょう。

(function(global, _) {
  // code
})(
  // 環境依存を解消するためのコード(本質的ではない)
  'undefined' === typeof window ?
    module.exports :
    window,
  'undefined' === typeof _ ?
    require('underscore') :
    _
);

この対応というのは、本質的なコードではない上にテストの信頼性も損なってしまいます。

またこの問題を解消できたとしても、DOM に依存するコードは単独でテストをしづらいという課題が残ります。


ブラウザで動作しているテストコードを、特別な変更無しで CI 環境でも動作させることができたら素敵ですよね。


というわけで、作ってみました。


* mocha-ci-driver を使うと

mocha-ci-driver は mocha で書かれているブラウザ用のテストを、Node.js 上でも動作させるためのドライバです。

これを使うと、ブラウザ用に書かれたテストを CI に組み込めます。
なので、普段の開発では CI で動作させておいて、ブラウザ互換を確認したいときは各ブラウザでテストを実行することができるようになります。


Node.js 用の設定はこんな感じです。

1. まず、ドライバを実行するためのファイルを追加します。
(値は各環境によって適宜変更してください。)

// ./test/driver.js
var Driver = require('mocha-ci-driver').Driver
  , basedir = __dirname + '/../'
  , port = 8080
  , testHtml = '/test/index.html'
  , driver = new Driver(basedir, port)

driver.run(testHtml);


2. 次に、普段利用しているテスト用の html を一部修正し、
html の中でなくドライバ側でテストを実行するよう設定します。
(mocha はテストを実行した後はテスト内容を捨ててしまうので、この設定が無いと、ドライバ側で実行すべきテストを取得できなくなってしまいます。)

(before)

<script>
  $(function () {
    mocha.run();
  });
</script>

(after)

<script>
  $(function () {
    // Node.js で実行時にはこのタイミングでテストを実行しない
    if (!/Node.js/.test(navigator.appName)) {
      mocha.run();
    }
  });
</script>

3. この設定が完了すれば、あとは Node.js で実行するだけです。

$ node ./test/driver.js


* mocha の対応バージョン

ただ、この mocha-ci-driver が対応しているのは、 visionmedia/mocha@a186b8dba1 以降になります。
2012.03.04 現在、 tag は切られていないので、 mocha-ci-driver を利用するためにはリポジトリから mocha を取得してきて make する必要があります。

$ git clone git://github.com/visionmedia/mocha.git mocha
$ cd mocha
$ make clean && make

これで mocha.js がビルドされるので、この mocha.js をテスト用の html で利用するようにしてください。


というわけで、 ブラウザでもサーバでも動作するテストに興味がある方は mocha-ci-driver 試してみてください:-)