23 February 2014

Jenkins, Grunt, Jasmine で JavaScript のテストを CI

jasmine で書いた js のテストを grunt で実行できるようにして jenkins で継続的に動作させる。

Gruntfile.js

まず Gruntfile.js には以下のようにする。

module.exports = function(grunt) {
    grunt.initConfig({
        jasmine: {
            all: {
                src: 'js/source/**/*.js',
                options: {
                    specs: 'js/spec/**/*.spec.js',
                    helpers: ['js/spec/helpers/jquery-1.11.0.min.js',
                              'js/spec/helpers/jasmine-jquery.js'],
                    keepRunner: true,
                    junit: {
                        path: 'build/jasmine-test/'
                    }
                }
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-jasmine');
};
  • js/source/**/*.js にテスト対象のコード
  • js/spec 以下にテスト関連のファイル
    • js/spec/*.spec.js にテストコード
    • js/spec/helpers にテストコードのヘルパー
    • js/spec/fixtures に fixture。今回はテストデータとなる html。
  • build/jasmine-test/ にテスト結果を出力

というディレクトリ構造にした。今回のテスト対象は外部のライブラリに依存していないが、たとえば jquery に依存しているなど外部のライブラリを使っているならば、js/spec/vendors 以下に依存ライブラリを入れるべきだ。

同様の理由で jasmine-jquery とそれが依存している jquery は、あくまでテストのためのライブラリで、本番のコードは依存していないので、helpers の下に配置している。

また今回は歴史的な事情でこのようなディレクトリの命名になっているが、spec/javascripts/* のような rails 文化に沿った規約を採用すると、よりわかりやすいかもしれない。

テストコード

テストコードの例。これを js/spec/your_method.spec.js などとして保存。

describe("yourMethod", function() {
    beforeEach(function() {
        jasmine.getFixtures().fixturesPath = 'js/spec/fixtures';
        loadFixtures('your_method.fixture.html');
    });

    it("should work fine", function (){
        // do something
    });
});

fixture のロードには jasmine-jqueryloadFixtures を使っている。loadFixtures はデフォルトで spec/javascripts/fixtures 以下のファイルを探しに行く。今回は js/spec/fixtures にフィクスチャを入れているので、fixturesPath プロパティを設定している。

fixture の取り扱いが便利なので、jasmine-jquery の fixture 系の機能だけを使っている。その他の jquery 的な機能は個買いは使っていない。

jenkins

jenkins のビルドの設定を以下のようにしておく。

npm install
grunt jasmine

ビルド後の処理として JUnitテスト結果の集計build/jasmine-test/*.xml を指定する。

参考