web-dev-qa-db-ja.com

CommonJS構文のファイルを使用したKarmaおよびRequireJSでのテスト

CommonJS構文で記述され、gruntタスクとgrunt-contrib-requirejsタスクを使用してソースファイルをAMD形式に変換し、1つの出力にコンパイルするangularアプリケーションに取り組んでいます。私の目標は、KarmaをRequireJSで動作させ、ソースファイルとスペックファイルをCommonJS構文で維持することです。

次のファイル構造を使用して、AMD形式で簡単なテストに合格することができました。

-- karma-test
   |-- spec
   |   `-- exampleSpec.js
   |-- src
   |   `-- example.js
   |-- karma.conf.js
   `-- test-main.js

および次のファイル:

karma.conf.js

// base path, that will be used to resolve files and exclude
basePath = '';

// list of files / patterns to load in the browser
files = [
  JASMINE,
  JASMINE_ADAPTER,
  REQUIRE,
  REQUIRE_ADAPTER,
  'test-main.js',
  {pattern: 'src/*.js', included: false},
  {pattern: 'spec/*.js', included: false}
];

// list of files to exclude
exclude = [];

// test results reporter to use
// possible values: 'dots', 'progress', 'junit'
reporters = ['progress'];

// web server port
port = 9876;

// cli runner port
runnerPort = 9100;

// enable / disable colors in the output (reporters and logs)
colors = true;

// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel = LOG_DEBUG;

// enable / disable watching file and executing tests whenever any file changes
autoWatch = true;

// Start these browsers, currently available:
browsers = ['Chrome'];

// If browser does not capture in given timeout [ms], kill it
captureTimeout = 60000;

// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun = false;

example.js

define('example', function() {
    var message = "Hello!";

    return {
        message: message
    };
});

exampleSpec.js

define(['example'], function(example) {
    describe("Example", function() {
        it("should have a message equal to 'Hello!'", function() {
            expect(example.message).toBe('Hello!');
        });
    });
});

test-main.js

var tests = Object.keys(window.__karma__.files).filter(function (file) {
      return /Spec\.js$/.test(file);
});

requirejs.config({
    // Karma serves files from '/base'
    baseUrl: '/base/src',

    // Translate CommonJS to AMD
    cjsTranslate: true,

    // ask Require.js to load these files (all our tests)
    deps: tests,

    // start test run, once Require.js is done
    callback: window.__karma__.start
});

ただし、私の目標は、次のように、ソースファイルとスペックファイルの両方をCommonJS構文で記述して同じ結果を得ることにあります。

example.js

var message = "Hello!";

module.exports = {
    message: message
};

exampleSpec.js

var example = require('example');

describe("Example", function() {
    it("should have a message equal to 'Hello!'", function() {
        expect(example.message).toBe('Hello!');
    });
});

しかし、cjsTranslateフラグがtrueに設定されているにもかかわらず、次のエラーが表示されます。

Uncaught Error: Module name "example" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
at http://localhost:9876/adapter/lib/require.js?1371450058000:1746

これをどのように達成できるかについてのアイデアはありますか?


編集:私はkarma-runnerリポジトリでこの問題を見つけました: https://github.com/karma-runner/karma/issues/552 そしてこの問題に役立つかもしれないいくつかのコメントがありますが私は今のところ彼らと運がありませんでした。

16
ekweible

私が見つけた解決策は、 grunt を使用し、いくつかのカスタムgruntタスクを作成することでした。プロセスは次のようになります。

ファイルパターンを使用してすべての仕様を検索し、それらをループして従来のAMDスタイルのrequireブロックを構築し、次のようなコードで一時ファイルを作成することにより、bootstrap requirejsファイルを構築するためのgruntタスクを作成します。

require(['spec/example1_spec.js'
,'spec/example2_spec.js',
,'spec/example3_spec.js'
],function(a1,a2){
// this space intentionally left blank
}, "", true);

上記のbootstrapファイルをコンパイルし、すべてのソースコード、仕様、およびライブラリを効果的に含む単一のjsファイルを出力するRequireJSgruntタスクを作成します。

   requirejs: {
        tests: {
            options: {
                baseUrl: './test',
                paths: {}, // paths object for libraries
                shim: {}, // shim object for non-AMD libraries
                // I pulled in almond using npm
                name: '../node_modules/almond/almond.min',
                // This is the file we created above
                include: 'tmp/require-tests',
                // This is the output file that we will serve to karma
                out: 'test/tmp/tests.js',
                optimize: 'none',
                // This translates commonjs syntax to AMD require blocks
                cjsTranslate: true
            }
        }
    }

カルマサーバーを手動で起動し、テスト用にコンパイルされた単一のjsファイルを提供するgruntタスクを作成します。

さらに、REQUIRE_ADAPTERファイルのkarma.conf.jsを捨てて、すべてのソースコードと仕様に一致するパターンではなく、コンパイルされた単一のjsファイルのみを含めることができたので、次のようになります。

// base path, that will be used to resolve files and exclude
basePath = '';

// list of files / patterns to load in the browser
files = [
  JASMINE,
  JASMINE_ADAPTER,
  REQUIRE,
  'tmp/tests.js'
];

// list of files to exclude
exclude = [];

// test results reporter to use
// possible values: 'dots', 'progress', 'junit'
reporters = ['progress'];

// web server port
port = 9876;

// cli runner port
runnerPort = 9100;

// enable / disable colors in the output (reporters and logs)
colors = true;

// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel = LOG_INFO;

// enable / disable watching file and executing tests whenever any file changes
autoWatch = true;

// Start these browsers, currently available:
browsers = ['PhantomJS'];

// If browser does not capture in given timeout [ms], kill it
captureTimeout = 60000;

// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun = true;

Requirejsコンパイルのgruntタスク構成では、テスト実行を開始するために アーモンド を使用する必要もありました(テスト実行はそれなしでハングします)。これは、上記のrequirejs grunt taskconfigで使用されていることがわかります。

12
ekweible

いくつかあります。まず第一に:私はあなたの質問のいくつかの詳細を見逃したかもしれません(それは非常に巨大なので)-それについては申し訳ありません。

要するに、Backbone-Boilerplate wipブランチテスト組織をチェックアウトすることをお勧めします: https://github.com/backbone-boilerplate/backbone-boilerplate/tree/wip

First:RequireJSは、ラップされていないrawcommon.jsモジュールをサポートしていません。 cjsTranslateは、ビルド中にCommonjsをAMD互換に変換するためのR.js(ビルドツール)オプションです。そのため、CJSrawモジュールを要求することは機能しません。この問題を解決するには、サーバーを使用して送信されたスクリプトをフィルタリングし、AMD形式にコンパイルします。 BBBでは、ファイルを静的サーブに渡してコンパイルします。

Second:Karma requirejsプラグインはうまく機能していません-そして、requireJSを直接使用するのはどういうわけか簡単です。 BBBでは、それが私たちがそれを管理した方法です: https://github.com/backbone-boilerplate/backbone-boilerplate/blob/wip/test/jasmine/test-runner.js#L16-L36

お役に立てれば!

1
Simon Boudrias