Karma を Require.js で実行するには、2 つのファイルが必要です。
karma.conf.js
— Karma を設定するファイルtest-main.js
— テスト用に Require.js を設定するファイルアプリケーションのディレクトリ構造が以下のようになっているとします。
$ tree
.
|-- index.html
|-- karma.conf.js
|-- lib
| |-- jquery.js
| |-- require.js
| `-- underscore.js
|-- src
| |-- app.js
| `-- main.js
`-- test
|-- appSpec.js
`-- test-main.js
3 directories, 9 files
最初のステップは、karma.conf.js
を作成することです。これはコマンドラインから実行できます。
$ karma init
これにより、ソースファイルとテストファイルへのパス、およびキャプチャするブラウザなど、いくつかの項目についてプロンプトが表示されます。
この例では Jasmine を使用しますが、他のテストフレームワークでも同様に動作します。
Require.js に対して「はい」を選択します。
「どのファイルを <script> タグでインクルードしますか?」 という質問に対しては、Require.js によってロードされないすべてのファイルを選択する必要があります。 通常は、test-main.js
ファイルのみを含める必要があります。このファイルは、Require.js を使用する場合、テストに対して main.js
がアプリケーションに対して持つ役割と同じ役割を果たします。
「ソースファイルとテストファイルはどこにありますか?」 という質問に対しては、Require.js でロードするすべてのファイルを選択します。 この例では、以下のファイルが必要です。
lib/**/*.js
— すべての外部ライブラリsrc/**/*.js
— ソースコードtest/**/*Spec.js
— すべてのテスト次に、ファイルを除外する際に、src/main.js
と入力します。テストではアプリケーションを実際に起動したくないためです。
これで、karma.conf.js
に以下の内容が含まれるようになります。
// list of files / patterns to load in the browser
module.exports = function(config) {
config.set({
frameworks: ['jasmine', 'requirejs'],
files: [
{pattern: 'lib/**/*.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'test/**/*Spec.js', included: false},
'test/test-main.js'
],
// list of files to exclude
exclude: [
'src/main.js'
]
});
};
files プロパティには、Karma ランナーで使用できるようにするすべてのファイルが含まれています。 デフォルトでは、included: false
オプションを使用しない限り、ファイルごとに script タグが作成されます。
requirejs の前に script タグを追加したい場合(requirejs の前に amd 互換スクリプトをロードするため)、requirejs とアダプタースクリプトを files リストに追加し、frameworks リストから requirejs を削除する必要があります。 これにより、順序を制御できます。 たとえば、requirejs の前に knockout.js
をロードするには...
config.set({
frameworks: ['jasmine'],
files: [
'knockout.js',
'node_modules/requirejs/require.js',
'node_modules/karma-requirejs/lib/adapter.js',
{pattern: 'lib/**/*.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'test/**/*Spec.js', included: false},
'test/test-main.js'
],
Require.js プロジェクトと同様に、テストをブートストラップするためのメインモジュールが必要です。 これは test/test-main.js
で行います。
/base
ディレクトリ #Karma は、/base
ディレクトリの下にファイルを配置します。 したがって、サーバー上では、ファイルへのリクエストは http://localhost:9876/base/*
の下で処理されます。
baseUrl
の Require.js 設定は、相対パスでロードされるモジュールの開始コンテキストを提供します。 Karma サーバー用にこの値を設定する場合、/base
で始める必要があります。 テストの baseUrl
は、ソースの相対 require を変更する必要がないように、src/main.js
のベース URL と同じフォルダにする必要があります。 したがって、ベース URL を src/
にするには、/base/src
と記述する必要があります。
Karma を使用すると、test-main.js
で指定されたファイルからすべてのテストファイルを簡単に見つけることができるため、すべてのテストファイルを自分でリストする必要はありません。Karma は window.__karma__.files
にすべてのファイルを含めているため、この配列をフィルタリングすることで、すべてのテストファイルを見つけることができます。
これで、Require.js にテストをロードするように指示できます。これは、テストを実行する前に依存関係を取得する必要があるため、非同期的に行う必要があります。 test/test-main.js
ファイルは最終的に次のようになります。
var TEST_REGEXP = /(spec|test)\.js$/i;
var allTestFiles = [];
// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
// If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
// then do not normalize the paths
var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');
allTestFiles.push(normalizedTestModule);
}
});
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: '/base/src',
// example of using a couple of path translations (paths), to allow us to refer to different library dependencies, without using relative paths
paths: {
'jquery': '../lib/jquery',
'underscore': '../lib/underscore',
},
// example of using a shim, to load non AMD libraries (such as underscore)
shim: {
'underscore': {
exports: '_'
}
},
// dynamically load all test files
deps: allTestFiles,
// we have to kickoff jasmine, as it is asynchronous
callback: window.__karma__.start
});
テストは、通常の Require.js モジュールとして記述できるようになりました。 すべてを define
でラップし、その内部で describe
や it
などの通常のテストメソッドを使用できます。 例:
define(['app', 'jquery', 'underscore', './test-helper'], function(App, $, _, testHelper) {
describe('just checking', function() {
testHelper.setup();
it('works for app', function() {
var el = $('<div></div>');
var app = new App(el);
app.render();
expect(el.text()).toEqual('require.js up and running');
});
it('works for underscore', function() {
// just checking that _ works
expect(_.size([1,2,3])).toEqual(3);
});
});
});
これで、コマンドラインからテストを実行できます。
$ karma start
Karma がすべてのファイルを監視し、変更があった場合に自動的にテストを実行するように設定していない場合は、次のように入力してテストを手動でトリガーできます。
$ karma run