2013-06-24 62 views
16

我正在研究以CommonJS语法编写的角度应用程序,并使用grunt-contrib-requirejs任务使用grunt任务将源文件转换为AMD格式并编译它放到一个输出文件中。我的目标是让Karma与RequireJS一起工作,并使用CommonJS语法保留我的源文件和规范文件。使用CommonJS语法对文件进行Karma和RequireJS测试

我已经能够得到一个简单的测试,在经过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!'); 
     }); 
    }); 
}); 

测试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 

关于如何完成这一任何想法?


编辑:我发现这个问题了卡玛 - 亚军回购:https://github.com/karma-runner/karma/issues/552并有一些意见,可能有助于解决这个问题,但我还没有任何与他们的运气至今。

回答

11

我最终发现的解决方案涉及使用grunt并编写一些自定义的grunt任务。这个过程是这样的:

创建一个咕task任务,通过使用文件模式查找所有规格,循环遍历它们并构建传统的AMD样式require块并创建一个类似这样的代码的临时文件来构建bootstrap requirejs文件:

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

创建编译上述引导文件并且输出单个JS文件,这将有效地包括所有的源代码,规格,和文库的RequireJS咕噜任务。

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

创建一个grunt任务,手动启动一个karma服务器并提供我们现在用于测试的单个已编译的js文件。

此外,我能够沟REQUIRE_ADAPTERkarma.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任务配置中,还需要使用almond以启动测试执行(测试执行将在没有它的情况下挂起)。你可以在上面的requirejs grunt任务配置中看到它。

1

有几件事情。首先:我可能错过了你的问题中的一些细节(因为它超级巨大) - 非常抱歉。

总之,你可能要签骨干,样板wip分支检测机构:https://github.com/backbone-boilerplate/backbone-boilerplate/tree/wip

首先:RequireJS不支持解开原始common.js模块。 cjsTranslate是一个R.js(构建工具)选项,用于在构建过程中将Commonjs转换为AMD兼容。因此,要求CJS原始模块将不起作用。要解决此问题,可以使用服务器来过滤发送的脚本并将其编译为AMD格式。在BBB,我们通过一个静态文件传递服务,以进行编译:

:卡玛requirejs插件无法正常工作超级好 - 它可以直接使用requireJS。在BBB,这就是我们如何管理它:https://github.com/backbone-boilerplate/backbone-boilerplate/blob/wip/test/jasmine/test-runner.js#L16-L36

希望这有助于!

+0

BBB链接已死,链接到同一个文件的提交重命名为:https://github.com/backbone-boilerplate/backbone-boilerplate/blob/eb172e0ac9accb16d1d46e288052be0bded052bb/test/runner.js – MrYellow

相关问题