简体   繁体   English

使用带有CommonJS语法文件的Karma和RequireJS进行测试

[英]Testing with Karma and RequireJS with files in CommonJS syntax

I'm working on an angular application that is written in CommonJS syntax and uses a grunt task with the grunt-contrib-requirejs task to translate the source files to AMD format and compile it into one output file. 我正在研究一个用CommonJS语法编写的角度应用程序,并使用grunt-contrib-requirejs任务的grunt任务将源文件转换为AMD格式并将其编译成一个输出文件。 My goal is to make Karma work with RequireJS and keep my source files and spec files in CommonJS syntax. 我的目标是使Karma与RequireJS一起工作,并将我的源文件和spec文件保存在CommonJS语法中。

I've been able to get a simple test passing in AMD format with the following file structure: 我已经能够通过以下文件结构以AMD格式传递一个简单的测试:

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

and the following files: 和以下文件:

karma.conf.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 example.js

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

    return {
        message: message
    };
});

exampleSpec.js 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 测试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
});

However, my goal is to write both the source file and the spec file in CommonJS syntax with the same results, like so: 但是,我的目标是用CommonJS语法编写源文件和spec文件,结果相同,如下所示:

example.js example.js

var message = "Hello!";

module.exports = {
    message: message
};

exampleSpec.js exampleSpec.js

var example = require('example');

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

But despite having the cjsTranslate flag set to true , I just receive this error: 但是尽管将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

Any ideas on how this can be accomplished? 关于如何实现这一点的任何想法?


Edit: I found this issue for the karma-runner repo: https://github.com/karma-runner/karma/issues/552 and there's a few comments that may help with this problem, but I haven't had any luck with them so far. 编辑:我发现了karma-runner repo的这个问题: https//github.com/karma-runner/karma/issues/552并且有一些评论可能有助于解决这个问题,但我没有任何运气到目前为止他们。

The solution I ended up finding involved using grunt and writing some custom grunt tasks. 我最终找到了使用grunt和编写一些自定义grunt任务的解决方案。 The process goes like this: 过程如下:

Create a grunt task to build a bootstrap requirejs file by finding all specs using a file pattern, looping through them and building out a traditional AMD style require block and creating a temporary file with code like this: 通过使用文件模式查找所有规范,循环遍历它们并构建传统的AMD样式需求块并使用以下代码创建临时文件来创建一个grunt任务来构建bootstrap requirejs文件:

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

Create a RequireJS grunt task that compiles the above bootstrap file and outputs a single js file that will effectively include all source code, specs, and libraries. 创建一个RequireJS grunt任务,编译上面的bootstrap文件并输出一个有效包含所有源代码,规范和库的单个js文件。

  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 } } } 

Create a grunt task that manually starts a karma server and serve the single compiled js file that we now have for testing. 创建一个grunt任务,手动启动karma服务器并提供我们现在用于测试的单个编译的js文件。

Additionally, I was able to ditch the REQUIRE_ADAPTER in the karma.conf.js file and then only include the single compiled js file instead of the patterns that matched all source code and specs, so it looks like this now: 另外,我能够karma.conf.js文件中的REQUIRE_ADAPTER ,然后只包含单个编译的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;

In the grunt task configuration for the requirejs compilation, it was also necessary to use almond in order to start the test execution (test execution would hang without it). 在requirejs编译的grunt任务配置中,还需要使用almond来启动测试执行(测试执行将在没有它的情况下挂起)。 You can see this used in the requirejs grunt task config above. 您可以在上面的requirejs grunt任务配置中看到这个。

There's a couple things. 有几件事情。 First of all: I might have missed some details in your question (as it is super huge) - so sorry about that. 首先:我可能已经错过了你问题中的一些细节(因为它超级巨大) - 很抱歉。

In short, you may want to checkout Backbone-Boilerplate wip branch testing organization: https://github.com/backbone-boilerplate/backbone-boilerplate/tree/wip 总之,你可能要签骨干,样板wip分支检测机构: https://github.com/backbone-boilerplate/backbone-boilerplate/tree/wip

First : RequireJS does not support unwrapped raw common.js module. 第一 :RequireJS不支持unwrapped raw common.js模块。 cjsTranslate is a R.js (the build tool) option to convert Commonjs to AMD compatible during build. cjsTranslate是一个R.js(构建工具)选项,用于在构建期间将Commonjs转换为AMD兼容。 As so, requiring a CJS raw module won't work. 因此,要求CJS原始模块将不起作用。 To resolve this issue, you can use a server to filter the scripts sent and compile them to AMD format. 要解决此问题,您可以使用服务器过滤发送的脚本并将其编译为AMD格式。 On BBB, we pass file through a static serve to compile them: 在BBB上,我们通过静态服务传递文件来编译它们:

Second : The Karma requirejs plugin isn't working super well - and it's somehow easy to use requireJS directly. 第二 :Karma requirejs插件不能很好地运行 - 并且它在某种程度上很容易直接使用requireJS。 On BBB, that's how we managed it: https://github.com/backbone-boilerplate/backbone-boilerplate/blob/wip/test/jasmine/test-runner.js#L16-L36 在BBB上,这就是我们管理它的方式: https//github.com/backbone-boilerplate/backbone-boilerplate/blob/wip/test/jasmine/test-runner.js#L16-L36

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM