如何在节点中使用spec – grunt + karma + jasmine

含糊的版本问题:

  • 如何使用grunt中的spec来使用require?

语境:

我正在做一个没有testing的现有节点项目,所以我读了一些,并意识到使用业力和茉莉花。

我读了一些Tutos(包括这些):

  • 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

所以我试图运行我的规格咕噜,得到这个错误:

X遇到一个声明exceptionReferenceError:找不到variables:require在file:///(…)-spec.js(line 2)(1)

这条线是这样的:

var myHelper = require(...); 

但是,如果我通过terminal“节点 – 茉莉花testing”使用它像一个魅力…

我的项目结构:

  • 控制器/
  • 助手/
  • 楷模/
  • node_modules /
  • 资源/
  • testing/
  • testing/规格/
  • 意见/
  • app.js
  • Gruntfile.js
  • 的package.json

在我的规范(内部testing/ spec /)我使用require('../../ helpers / helper.js'),这对节点茉莉花是好的,但没有与咕噜声。

节点茉莉花testing:

…..

在0.015秒内完成5个testing,5个断言,0个失败,0个跳过

咕噜:

运行“茉莉花:关键”(茉莉花)任务通过PhantomJStesting茉莉花规格

ReferenceError:无法findvariables:需要在app.js:1 Service HelpertestingX遇到声明exceptionReferenceError:无法findvariables:require在file:///(…)/ test / spec / serviceHelper- spec.js(第2行)(1)

1个规格0.005秒。

1次失败警告:任务“jasmine:pivotal”失败。 使用–force继续。

由于警告而中止。

我有所有的软件包安装到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'); } 

感谢您的关注。

怎么样

这取决于:

  1. 如果您有一些应用程序代码需要根据浏览器进行testing(例如, AngularBackbone等) – 请使用Karma并且不要使用require 。 然后确保你的helpers.js文件在testing之前加载。

     // @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); 
  2. 如果你不需要在浏览器上运行你的testing(也就是严格testingNodeJS代码),你可以通过移除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来运行你的testing。 Karma只是在您select的浏览器中加载文件,并按照您在karma.conf.js提供的顺序执行它们。 它在内部使用您提供的testing框架(在这种情况下是Jasmine ),针对您提供的浏览器(在本例中为PhantomJS )运行testing。

与所有的JavaScript一样,variables上下文是由它所包含的闭包定义的。

  • Jasmine二进制文件在内部使用NodeJS ,它仿效CommonJS的要求 ,在你的节点应用程序的上下文中使你的require函数可用。

  • Karma runner做了相当于为浏览器编写<script src="[path]">标记的代码,然后将相应的文件加载到PhantomJs 。 因此,您的JavaScript上下文是全局的,并且您的文件只能访问全局上下文。 在浏览器中,全局上下文由附加到window对象的所有东西来定义,并且window.require本身并不存在。