模糊版本问题:
- 如何在带有 grunt 的规范中使用 require?
上下文:
我正在处理一个尚未测试的现有 Node 项目,所以我阅读了一些并意识到使用 karma 和 jasmine。
我读了一些教程(包括这些):
- http://kwilson.me.uk/blog/use-karma-and-grunt-to-run-your-jasmine-tests-in-real-time/
- http://ahexamples.blogspot.com.br/2014/03/example-of-jasmine-karma-sonar-grunt.html
所以我试图用 grunt 运行我的规范并得到这个错误:
X encountered a declaration exception ReferenceError: Can't find variable: require in file:///(...)-spec.js (line 2) (1)
这条线是这样的:
var myHelper = require(...);
但是如果我通过终端“node-jasmine test”使用它,它就像一个魅力......
我的项目结构:
- controllers/
- helpers/
- models/
- node_modules/
- resources/
- test/
- test/spec/
- views/
- app.js
- Gruntfile.js
- package.json
在我的规范中(在 test/spec/中)我使用了一个 require('../../helpers/helper.js') 这对 node-jasmine 没问题,但对 grunt 不行。
Node Jasmine 测试:
.....
Finished in 0.015 seconds 5 tests, 5 assertions, 0 failures, 0 skipped
咕噜声:
Running "jasmine:pivotal" (jasmine) task Testing jasmine specs via PhantomJS
ReferenceError: Can't find variable: require at app.js:1 Service Helper Tests X encountered a declaration exception ReferenceError: Can't find variable: require in file:///(...)/test/spec/serviceHelper-spec.js (line 2) (1)
0.005 秒内 1 个规范。
1 failures Warning: Task "jasmine:pivotal" failed. Use --force to continue.
由于警告而中止。
我已将所有包安装到 node_modules(package.json 中的依赖项中没有任何内容)并且我的 Gruntfile.js 是:
'use strict';
module.exports = function(grunt) {
var $srcFiles = 'app.js';
var $testFiles = 'test/spec/*-spec.js';
var $outputDir = 'test/target'
var $junitResults = $outputDir + '/junit-test-results.xml';
var $jasmineSpecRunner = $outputDir + '/_SpecRunner.html';
var $coverageOutputDir = $outputDir + '/coverage';
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Jasmine test
jasmine: {
pivotal: {
src: $srcFiles,
options: {
specs: $testFiles,
outfile: $jasmineSpecRunner,
keepRunner: 'true' // keep SpecRunner/outfile file
}
}
},
// coverage using Karma
karma: {
continuous: {
singleRun: 'true',
browsers: [ 'PhantomJS' ]
},
options: {
plugins: [
'karma-jasmine',
'karma-phantomjs-launcher',
'karma-junit-reporter',
'karma-coverage'
],
frameworks: [ 'jasmine' ],
files: [ $srcFiles, $testFiles ],
reporters: [ 'junit', 'coverage' ],
junitReporter: {
outputFile: $junitResults
},
preprocessors: {
// source files must be a literal string
'helpers/*.js': [ 'coverage' ]
},
coverageReporter: {
type: 'lcov',
dir: $coverageOutputDir
}
}
},
// export Karma coverage to SonarQube
karma_sonar: {
your_target: {
// properties for SonarQube dashboard
project: {
key: 'net.ahexample:ahexample-jasmine-karma-sonar',
name: 'Jasmine with Karma and SonarQube Example',
version: '0.0.1'
}
// sources property is set at runtime (see below)
}
},
clean: [ $outputDir ]
});
/*
* Task to set karma_sonar's sources property.
* This is needed because karma (coverage) stores its results in a
* directory whose name uses the browser's user agent info
* (name/version and the platform name).
* The latter may well he different to the OS name and so its needs an
* OS to platform translator.
* For example, OS name for Apple Mac OS X is Darwin.
*/
grunt.registerTask('set-karma-sonar-sources-property', function() {
var $done = this.async();
var $phantomjs = require('karma-phantomjs-launcher/node_modules/phantomjs');
var $spawn = require('child_process').spawn;
var $phantomUserAgent = $spawn($phantomjs.path,
// phantomjs script to print user agent string
[ 'lib/phantomjs-useragent.js' ]
);
/*
* Construct coverage LCOV file path from PhantomJS'
* user agent string, then use it to set karma_sonar's
* sources property.
*/
$phantomUserAgent.stdout.on('data', function(msg) {
var $useragent = require('karma/node_modules/useragent');
var $agent = $useragent.parse(msg);
// An example of dirName is 'PhantomJS 1.9.7 (Mac OS X)'
var $dirName = $agent.toAgent() + ' (' + $agent.os + ')';
var $coverageResults = $coverageOutputDir + '/' + $dirName + '/lcov.info';
var $sonarSources = makeSonarSourceDirs($srcFiles, $coverageResults);
var $karmaSonarConfig = 'karma_sonar';
var $ksConfig = grunt.config($karmaSonarConfig);
grunt.log.writeln('coverage LCOV file: ' + $coverageResults);
$ksConfig['your_target']['sources'] = $sonarSources;
grunt.config($karmaSonarConfig, $ksConfig);
});
$phantomUserAgent.on('close', function(exitCode) {
$done();
});
/*
* Create sonar source object for each directory of source file pattern.
*/
function makeSonarSourceDirs($filesPattern, $coverageResults) {
var $path = require('path');
var $dirs = [];
grunt.file.expand(
{
filter: function($filePath) {
$dirs.push({
path: $path.dirname($filePath),
prefix: '.', // path prefix in lcov.info
coverageReport: $coverageResults,
testReport: $junitResults
});
}
},
$filesPattern
);
return $dirs;
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-jasmine');
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-karma-sonar');
grunt.registerTask('test', [ 'jasmine', 'karma:continuous' ]);
grunt.registerTask('sonar-only', [ 'set-karma-sonar-sources-property', 'karma_sonar' ]);
grunt.registerTask('sonar', [ 'test', 'sonar-only' ]);
grunt.registerTask('default', 'test');
}
感谢您的关注。
最佳答案
如何
这取决于:
如果您有一些应用程序代码需要针对浏览器进行测试(例如
Angular
、Backbone
等)- 使用Karma
并且不要使用require
.然后确保您的helpers.js
文件在测试本身之前加载。// @file Gruntfile.js // https://github.com/karma-runner/grunt-karma grunt.initConfig({ karma: { client: { options: { files: ['client/*.js', 'helpers/*.js', 'test/*.js'] } } } }); // @file helpers.js (function () { window.helpers = { foo: function () { return 'bar'; } }; })(); // @file spec.js (function (helpers) { it('does the thing', function () { expect(helpers.foo()).toBe('bar'); }); })(window.helpers);
如果您不需要针对浏览器运行测试(即您严格测试
NodeJS
代码),您可以通过删除Karma
来简化您的设置并严格使用Jasmine
:// @file Gruntfile.js // https://github.com/gruntjs/grunt-contrib-jasmine grunt.initConfig({ jasmine: { server: { src: 'server/*.js', options: { specs: 'test/*.js', helpers: 'helpers/*.js' } } } }); // @file helpers.js (function () { module.exports = { foo: function () { return 'bar'; } }; })(); // @file spec.js (function () { var helpers = require('helpers'); // require is available it('does the thing', function () { expect(helpers.foo()).toBe('bar'); }); })();
为什么
require
不存在,因为您正在使用 Karma
运行你的测试。 Karma
只需在您选择的浏览器中加载文件并按照您在 karma.conf.js
中提供的顺序执行它们.它在内部使用您提供的测试框架(在本例中为 Jasmine
)针对您提供的浏览器(在本例中为 PhantomJS
)运行测试。
与所有 JavaScript 一样,变量上下文由它所在的闭包定义。
Jasmine
二进制内部使用NodeJS
,这emulates CommonJS require , 使得require
您可以在 Node 应用程序的上下文中使用的功能。Karma
运行者所做的相当于写作<script src="[path]">
标记到浏览器,然后浏览器分别将相应的文件加载到PhantomJs
中.因此,您的 javascript 上下文是全局的,您的文件只能访问全局上下文。在浏览器中,全局上下文由附加到window
的所有内容定义。对象,和window.require
不存在。
关于javascript - 如何在规范中使用 require - grunt + karma + node 中的 jasmine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25413099/