読者です 読者をやめる 読者になる 読者になる

hakobera's blog

技術メモ。たまに雑談

mocha と Jenkins で Node.js の CI 環境を構築する

 最近、mocha をつかってテストを書くのが楽しくなってきました。でも、テストの数が増えてくるとローカルでの実行だけでなく、CI 環境が欲しくなりますよね。github にあげられるようなプロジェクトだったら、Travis CI も良いですが、実際に仕事で使うとなると、既存の Jenkins と組み合わせてやる必要ができてきたので、実際にやってみました。

 基本的な手順は以下の通りです。

  1. mocha でテスト結果を TAP 形式でファイルに出力する
  2. 出力したファイルを Jenkins の TAP Plugin に読み込ませる

 簡単ですね。

実際にやってみた

というわけで、以下のような最小構成で試してみます。

myapp
 |- lib
 |    |- calc.js
 |
 |- test
 |    |- calc.test.js
 |
 |- package.json

ここには書いていませんが、実際は git で管理していて、node_modules を .gitignore で管理外に指定しています。

calc.js
exports.add = function(x, y) {
  return x+ y;
};
calc.test.js

結果を見るためにわざと2つめのテストは失敗させています。

var calc = require('../lib/calc');

var should = require('should');

describe('calc', function() {
  describe('.add', function() {
    it('should return sum of 2 arguments', function() {
      var result = calc.add(1, 2);
      result.should.equal(3);
    });

    it('error', function() {
      var result = calc.add(1, 3);
      result.should.equal(3);
    });
  });
});
package.json
{
  "name": "myapp", 
  "version": "0.0.1", 
  "devDependencies": {
    "mocha": "0.7.0", 
    "should": "0.4.2"
  }
}
Jenkins の事前準備
  • node と npm を Jenkins の実行ユーザから実行できるように PATH を設定しておく
  • Jenkins に TAP Plugin をインストールしておく
Jenkins の設定

フリースタイルプロジェクトを作成し、SCM の設定をし、そしてビルドでシェルの実行を選択し、以下を入力します。

npm install -d
$WORKSPACE/node_modules/mocha/bin/mocha --reporter tap > mocha-test-results.txt

f:id:scalar:20111219215447p:image

 npm install をテストの前に実行しておくことで、依存ライブラリが自動的にインストールされます。テストに使う mocha 自体も node_modules 配下にローカルインストールされたものを利用します。(複数プロジェクトで異なる Node のバージョンを使っている場合は、npm install の前に nvm などを使って明示的に Node のバージョンを切り替える処理をすることもできます。)

 最後にビルド後の処理で、Publish TAP Results にチェックを入れて、上記で出力したファイル名を指定します。

f:id:scalar:20111219215448p:image

実行結果

プロジェクトの状態
f:id:scalar:20111219221431p:image

TAP Test Result
f:id:scalar:20111219221433p:image

課題とまとめ

 mocha と TAP plugin の制限としては、結果ファイルが1つしか取れないので、複数のテストファイルがあった場合、どのファイルのテストが失敗したのかわかりづらい、というのがあります。

 この辺は、テストをファイルごとに実行するツールを書いて、tap2junit を使って JUnit 形式に変換したものを Jenkins に読み込ませれば解決するのですが、そこまで大規模でない場合は今回紹介した手法で十分かと思っています。

 Node.js で CI できるようになったので、仕事でも安心して使えるようになりました。mocha と Jenkins いいね!