Karma + Mocha でRequreJSを使ったJavaScriptをテストする
たまにやると忘れてるのでメモ。
Karmaはnode.jsベースのテストランナーで、ターミナルからテストを実行できて、複数のブラウザを立ち上げてテストを実行したり、ファイルの変更を監視して自動でテストを実行したりもできます。
RequireJSを使ってるJavascriptに対して、テストフレームワークとしてmocha、アサーションライブラリとしてexpectを使ったテストを書き、Karmaで実行します。
※2014/3/12追記 使用したバージョンは以下。
- node v0.10.25
- npm 1.3.24
- karma 0.12.0
追記ここまで。
最終的にはこんな感じに。
$ tree . |-- karma.conf.js |-- package.json |-- src | `-- js | |-- app.js | |-- lib | | |-- require.js | | `-- underscore.js | `-- require.config.js `-- test `-- js |-- appSpec.js `-- require.config.js
コードの準備
プロダクトコードがsrc/app.js、RequireJSとUnderscore.jsはダウンロードしてsrc/libへ。無理矢理Underscore.jsを使ったプロダクトコードを用意してみる 。
// src/app.js define(['underscore'], function(){ return { max: function(a, b, c){ return _.max([a, b, c]); } }; });
テストコードがtest/appSpec.js。
// test/appSpec.js define(['app'], function(app){ describe('appモジュールのテスト', function(){ it('maxメソッドのテスト', function(){ expect(app.max(1,2,3)).to.be(3); }); }); });
package.jsonを用意。
{ "name": "karma-sample", "version": "0.0.1" }
Karmaをインストール
Karmaをインストールする。
$ npm install -g karma-cli $ npm install --save-dev karma
Karmaの設定ファイルを作成
karma initで設定ファイルを生成
Karma initを実行して質問に答えていく。そうするとkarma.conf.jsが生成される。
$ karma init Which testing framework do you want to use ? Press tab to list possible options. Enter to move to the next question. > mocha Do you want to use Require.js ? This will add Require.js plugin. Press tab to list possible options. Enter to move to the next question. > yes Do you want to capture a browser automatically ? Press tab to list possible options. Enter empty string to move to the next question. > Chrome >_ What is the location of your source and test files ? You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js". Enter empty string to move to the next question. > src/**/*.js > test/**/*Spec.js >_ Should any of the files included by the previous patterns be excluded ? You can use glob patterns, eg. "**/*.swp". Enter empty string to move to the next question. > src/require.config.js WARN [init]: There is no file matching this pattern. >_ Which files do you want to include with <script> tag ? This should be a script that bootstraps your test by configuring Require.js and kicking __karma__.start(), probably your test-main.js file. Enter empty string to move to the next question. > test/require.config.js WARN [init]: There is no file matching this pattern. > Do you want Karma to watch all the files and run the tests on change ? Press tab to list possible options. > yes
Karmaのプラグインをインストール
Karmaで、requirejs、mocha、expectを使うためのプラグインをインストールする。
$ npm install --save-dev karma-expect
生成されたkarma.conf.jsを確認
生成されたkarma.conf.jsを中身を見るといろいろと設定項目が。
frameworks
は、karmaが使うプラグインを指定する。mochaとrequirejsが記述されているが、expectが記述されていないので追記する。
// frameworks to use frameworks: ['mocha', 'requirejs', 'expect'],
files
には、テストで使うjsファイルを指定する。karma init
時に指定したパターンとtest/require.config.jsが記述されている。
// list of files / patterns to load in the browser files: [ 'test/require.config.js', {pattern: 'src/**/*.js', included: false}, {pattern: 'test/**/*Spec.js', included: false} ],
'test/require.config.js'
のように単純にファイル(ワイルドカード可)を指定する方法と、{pattern: 'src/**/*.js', included: false}
のようにJSONでオプションと併せて指定することもできる。
src/**/*.js
とtest/**/*Spec.js
には、included: false
というオプションがついているが、これはkarmaがブラウザを立ち上げたときにscriptタグでjsファイルを読み込まないための指定。scriptタグではなくRequireJSを使ってjsファイル読み込むのでこのオプションが付与される。
exclude
には、テスト実行時に読み込みたくないファイルを指定。karma init
時に指定したパターンが記述される。テスト用のrequire.config.jsを使うため、プロダクトコード用のrequire.config.jsを指定してテスト実行時には読み込まないようにする。
// list of files to exclude exclude: [ 'src/require.config.js' ],
他の設定項目は、RequireJSを使わない場合といっしょ。
テスト用のrequire.configを設定
テスト実行時はプロダクトコード用のrequire.configを使わない。代わりにテスト用のrequire.configを設定する。
プロダクトコード用のrequire.configとの違いは、baseUrlとdepsとcallback。
// test/require.config.js var tests = []; for (var file in window.__karma__.files) { if (window.__karma__.files.hasOwnProperty(file)) { if (/Spec\.js$/.test(file)) { tests.push(file); } } } require.config({ baseUrl: "/base/src", paths: { "underscore": "lib/underscore" }, shim: { "underscore": { exports: "_" } }, deps: tests, callback: window.__karma__.start });
baseUrl
- /baseで始まるパスを設定する。karmaを実行すると、http://localhost:9876/base がkarma.conf.jsが存在するディレクトリになる。そのため、プロダクトコードの
baseUrl
と同じディレクトリを指すように、baseUrl
を/base/srcに設定する。
- /baseで始まるパスを設定する。karmaを実行すると、http://localhost:9876/base がkarma.conf.jsが存在するディレクトリになる。そのため、プロダクトコードの
deps
- テストコードを指定する。
window.__karma__.files
にkarma.conf.jsのfilesで指定したファイルが格納されているので、テストコード(ファイル名がSpec.jsで終わっているファイル)のみをtests
配列に格納して、deps
に指定する。
- テストコードを指定する。
callback
window.__karma__.start
を指定する。これで、deps
に記述したテストコードが全てブラウザに読み込まれた後に、window.__karma__.start
が実行されテストが動作する。
karmaを実行
これで準備ができたので、あとは以下のコマンドで実行。
$ karma start karma.conf.js
Gruntでkarma実行
gruntからkarmaを実行できると他のタスクと組み合わせたりできて便利。ということで、gruntとgrunt-karmaをインストール。
$ npm install --save-dev grunt grunt-karma
karmaタスクを定義して、
// Gruntfile.js module.exports = function(grunt){ grunt.initConfig({ karma: { unit: { configFile: 'karma.conf.js' } } }); grunt.loadNpmTasks('grunt-karma'); };
実行する。
$ grunt karma