LoginSignup
6

More than 5 years have passed since last update.

Grunt で Jasmine を使ったテスト環境を作る

Posted at

たまにしか書かない JavaScript でもちゃんとテストを書く習慣を身につけたいと思い、 Grunt で Jasmine によるテスト実行環境を作ってみた。

grunt-contrib-jasmine を使う。

gruntjs/grunt-contrib-jasmine
https://github.com/gruntjs/grunt-contrib-jasmine

準備

プロジェクト用のディレクトリを作成して grunt とプラグインをインストール。

% mkdir -p jasmine-test/{src/js,spec} && cd jasmine-test
% npm init
% npm install grunt grunt-contrib-jasmine --save-dev

これでディレクトリ構造は以下のようになる。

jasmine-test
 ├── node_modules
 │     ├── grunt
 │     └── grunt-contrib-jasmine
 ├── package.json
 ├── spec
 └── src
        └── js

JavaScript のテスト

テスト対象の javascript ファイルを作成する。

src/js/foo.js
var Foo = (function() {
    function Foo() {}
    Foo.prototype.name = function() {
        return 'Foo';
    };
    return Foo;
})();

対応する spec ファイルを作成。

spec/foo.spec.js
describe('Foo', function() {
    var foo;
    beforeEach(function() {
        foo = new Foo();
    });

    it('should return name', function (){
        expect(foo.name()).toEqual('Foo');
    });
});

Gruntfile.js を作成。

% vim Gruntfile.js

内容は以下のようにした。

Gruntfile.js
module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        jasmine: {
            all: {
                src: 'src/js/**/*.js',
                options: {
                    specs: 'spec/**/*.spec.js',
                },
            },
        },
    });
    grunt.loadNpmTasks('grunt-contrib-jasmine');
    grunt.registerTask('default', ['jasmine']);
};

実行してみる。

% grunt
Running "jasmine:all" (jasmine) task
Testing jasmine specs via PhantomJS

 Foo
   ✓ should return name

1 spec in 0.002s.
>> 0 failures

Done, without errors.

上手く動いてるっぽい。
試しに返す文字列を変更して再度実行。

% grunt
Running "jasmine:all" (jasmine) task
Testing jasmine specs via PhantomJS

 Foo
   X should return name
     Expected 'Bar' to equal 'Foo'. (1)

1 spec in 0.003s.
>> 1 failures
Warning: Task "jasmine:all" failed. Use --force to continue.

Aborted due to warnings.

ちゃんとエラーになった。

CoffeeScript のテスト

次は CoffeeScript に対しても spec を実行できるようにしてみる。

直接 coffee に対して spec を実行する方法もありそうだけど、軽く調べた感じでは見つけられなかったので、一旦 js に変換してから spec が実行されるようにした。

先ほどのプロジェクトディレクトリ下に追加で CoffeeScript 用のディレクトリを作成し、 grunt-contrib-coffee をインストール。

% mkdir src/coffee
% npm install grunt-contrib-coffee --save-dev

これでディレクトリ構造は以下のようになる。

jasmine-test
 ├── Gruntfile.js
 ├── node_modules
 │     ├── grunt
 │     ├── grunt-contrib-coffee
 │     └── grunt-contrib-jasmine
 ├── package.json
 ├── spec
 │     └── foo.spec.js
 └── src
        ├── coffee
        └── js

テスト対象の CoffeeScript を作成。

src/coffee/bar.coffee
class Bar
  name: ->
    'Bar'

spec も coffee で書いて変換後に実行、としたいところだが、取り敢えず今回は js で作成。

spec/bar.spec.js
describe('Bar', function() {
    var bar;
    beforeEach(function() {
        bar = new Bar();
    });

    it('should return name', function (){
        expect(bar.name()).toEqual('Bar');
    });
});

Gruntfile.js を以下のように変更。
coffeeoptionsbare: true が無いと変換後の js が無名関数で囲まれて spec から参照できなくなるので注意。

Gruntfile.js
module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        coffee: {
            compile: {
                options: {
                    bare: true,
                },
                files: [{
                    expand: true,
                    cwd: 'src/coffee',
                    src: ['*.coffee'],
                    dest: 'src/js/',
                    ext: '.js',
                }]
            }
        },
        jasmine: {
            all: {
                src: 'src/js/**/*.js',
                options: {
                    specs: 'spec/**/*.spec.js',
                },
            },
        },
    });
    grunt.loadNpmTasks('grunt-contrib-coffee');
    grunt.loadNpmTasks('grunt-contrib-jasmine');
    grunt.registerTask('default', ['coffee', 'jasmine']);
};

実行。

% grunt
Running "coffee:compile" (coffee) task
>> 1 files created.

Running "jasmine:all" (jasmine) task
Testing jasmine specs via PhantomJS

 Bar
   ✓ should return name
 Foo
   ✓ should return name

2 specs in 0.005s.
>> 0 failures

Done, without errors.

上手く動いたっぽい。
あとは以前調べた Grunt で複数の CoffeeScript を一つの無名関数内にまとめる あたりと組み合わせて

  1. coffee でコード、spec を書く
  2. どちらも js にコンパイルして spec 実行
  3. アプリケーションコードを一つの js に結合して無名関数で囲む

とかやれば良さそう。

参考

grunt.js - grunt+jasmineな環境作成手順 - Qiita
http://qiita.com/ampersand/items/0811f788accd3651e04a

Jenkins, Grunt, Jasmine で JavaScript のテストを CI - Please Sleep
http://please-sleep.cou929.nu/javascript-ci-with-jasmine-grunt-jenkins.html

coffeescript自動コンパイルでjasmine自動テストなgrunt環境構築 - よしそぶろぐ
http://blog.yoshiso.net/post/63619404740/coffeescript-jasmine-grunt

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6