Grunt - Karma 单元测试
2016-06-08 16:37
274 查看
http://www.cnblogs.com/haogj/p/4813155.html
Karma 是 Goolge 开源的一个 Test runner, 可以配合 Grunt 使用。
http://karma-runner.github.io/
官网中的文档其实分多钟版本,不同版本的 karma 使用也有所不同,注意页面右上角的版本信息。
https://github.com/litixsoft/karma-mocha-reporter
使用 npm init 来创建 package.json 项目文件。
安装 Karma
安装 grunt-karma 插件。
安装之后,在 node_modules 中实际上有了 grunt, grunt-karma, 以及 karma 三个组件。
继续安装 karma 的插件。
先安装 chrome 的启动器。
单元测试 jasmine.
单元测试的输出报表格式 mocha.
angular 插件
requirejs 插件。
karma 的运行配置可以保存在独立的文件中,也可以在 Gruntfile.js 中直接配置,由于 karma 的配置参数较多,建议保存在独立的配置文件中。
这样,我们可以针对不同的测试场景,创建不同的 karma 配置文件,最后通过 grunt 来使用。
karma 配置文件中的 basePath 是一个非常重要的参数,用来表示 karma 配置文件中的其它相对路径所依赖的起点。
如果这是一个对象路径,就会相对于配置文件来定位。
默认是 '', 也就是说配置文件所在的目录就是相对的根目录了。
在 karma 实际运行的时候,这个目录会被自动映射到 /base 之下。
files 中配置可以通过 karma 服务器访问哪些文件,在这里列出的文件,才可以通过 HTTP 访问到。当使用对象方式表示路径的时候,included 表示 karma 是不是需要自动生成一个 script 标记来加载特定的脚本,设置为 false 表示不生成这个标记,而 served 则表示是否可以通过 karma 的网站服务器访问这个文件。
plugins 在 v0.13 中可以不同配置,karma 会自动加载位于 node_modules 中的 karma-* 的 karma 模块。
在配合 requirejs 的时候,我们还需要一个 main.js 文件对 requirejs 进行配置。
在 requirejs 中也有一个 baseUrl 配置参数,这里一定要考虑刚才karma 的 basePath 进行配置,由于在 karma 的网站中,前面又添加了 /base ,所以,现在 requirejs 的 baseUrl 就会变成 /base/src/js 了。
这样,修改了 baseUrl, 我们其它的模块 Id 就不用变化了。
我们希望能够通过 karma 直接加载测试并执行测试,所以,karma 帮助我们生成了一段脚本,从我们网站中的脚本文件中筛选出测试文件,直接加载执行,脚本通过正则表达式 /(spec|test)\.js$/i 来筛选,可以看到,它直接检查脚本文件名中,以 spec.js 或者 test.js 结尾的脚本文件。找到之后,通过 requirejs 配置中的 deps 提前加载并执行。
测试也是一个模块,一定要在测试的依赖项中,将测试所依赖的模块加载进来。
执行之后的输出如下:
另外,文件名称的大小写问题,在 Windows 系统下大小写不敏感,但是,在 Linux 服务器上,大小写不同将是不同的文件。注意 Karma 服务器中,即使在 Windwos 系统下,也会区分大小写。
在配合 requirejs 时,关键是一定要通过 requirejs 来加载你的模块,而不是直接嵌入带页面中。
http://requirejs.org/docs/errors.html#mismatch
http://icodeit.org/2013/10/using-karma-as-the-javascript-test-runner/
Karma 是 Goolge 开源的一个 Test runner, 可以配合 Grunt 使用。
1. 相关插件介绍
1.1 Karma 的官网
http://karma-runner.github.io/
官网中的文档其实分多钟版本,不同版本的 karma 使用也有所不同,注意页面右上角的版本信息。
1.2 配合 Grunt 的插件 grunt-karma
https://github.com/karma-runner/grunt-karma1.3 karma 用来启动 chrome 的 karma 插件
https://github.com/karma-runner/karma-chrome-launcher1.4 jasmine 单元测试插件
https://github.com/karma-runner/karma-jasmine1.5 单元测试的报表格式
单元测试默认提供了两种输出:'dots', 'progress' ,都比较简单,希望看到测试的详细输出,可以使用 reporter 插件,这里是其中之一:mochahttps://github.com/litixsoft/karma-mocha-reporter
1.6 angularJS 插件
https://github.com/karma-runner/karma-ng-scenario1.7 requirejs 模块化插件
https://github.com/karma-runner/karma-requirejs2. 安装插件
2.1 创建 package.json使用 npm init 来创建 package.json 项目文件。
PS C:\study\demo> npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg> --save` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. name: (demo) demo version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) MIT About to write to C:\study\demo\package.json: { "name": "demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "MIT" } Is this ok? (yes) y PS C:\study\demo>
安装 Karma
PS C:\study\protocat> npm install karma --save-dev npm WARN package.json app@1.0.0 No description npm WARN package.json app@1.0.0 No repository field. npm WARN package.json app@1.0.0 No README data npm WARN optional dep failed, continuing fsevents@1.0.0 | > bufferutil@1.2.1 install C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\bufferutil > node-gyp rebuild C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\bufferutil>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node rebuild ) Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch. bufferutil.cc C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\limits(214): warning C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc [C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\bufferutil\build\bufferutil.vcxproj] Creating library C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\bufferutil\build\Release\bufferutil.lib and object C:\study\protocat\node_modules\karma\node_modules\s ocket.io\node_modules\engine.io\node_modules\ws\node_modules\bufferutil\build\Release\bufferutil.expGenerating code Finished generating code bufferutil.vcxproj -> C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\bufferutil\build\Release\\bufferutil.node | > utf-8-validate@1.2.1 install C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\utf-8-validate > node-gyp rebuild C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\utf-8-validate>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node rebuild ) Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch. validation.cc C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\limits(214): warning C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc [C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\utf-8-validate\build\validation.vcxproj] Creating library C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\utf-8-validate\build\Release\validation.lib and object C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\utf-8-validate\build\Release\validation.expGenerating code Finished generating code validation.vcxproj -> C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\engine.io\node_modules\ws\node_modules\utf-8-validate\build\Release\\validation.node / > utf-8-validate@1.2.1 install C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\utf-8-validate > node-gyp rebuild C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\utf-8-validate>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node rebuild ) Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch. validation.cc C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\limits(214): warning C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc [C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\utf-8-validate\build\validation.vcxproj] Creating library C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\utf-8-validate\build\Release\validation.lib and object C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\utf-8-validate\build\Release\validation.expGenerating code Finished generating code validation.vcxproj -> C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\utf-8-validate\build\Release\\validation.node | > bufferutil@1.2.1 install C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\bufferutil > node-gyp rebuild / C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\bufferutil>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node rebuild ) Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch. bufferutil.cc C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\limits(214): warning C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc [C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\bufferutil\build\bufferutil.vcxproj] Creating library C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\bufferutil\build\Release\bufferutil.lib and object C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\bufferutil\build\Release\bufferutil.exp Generating code Finished generating code bufferutil.vcxproj -> C:\study\protocat\node_modules\karma\node_modules\socket.io\node_modules\socket.io-client\node_modules\engine.io-client\node_modules\ws\node_modules\bufferutil\build\Release\\bufferutil.node karma@0.13.10 node_modules\karma ├── di@0.0.1 ├── rimraf@2.4.3 ├── graceful-fs@4.1.2 ├── mime@1.3.4 ├── colors@1.1.2 ├── bluebird@2.10.1 ├── http-proxy@1.11.2 (eventemitter3@1.1.1, requires-port@0.0.1) ├── source-map@0.4.4 (amdefine@1.0.0) ├── useragent@2.1.7 (lru-cache@2.2.4) ├── optimist@0.6.1 (wordwrap@0.0.3, minimist@0.0.10) ├── dom-serialize@2.2.0 (void-elements@1.0.0, custom-event@1.0.0, ent@2.2.0, extend@2.0.1) ├── minimatch@2.0.10 (brace-expansion@1.1.0) ├── glob@5.0.14 (path-is-absolute@1.0.0, inherits@2.0.1, inflight@1.0.4, once@1.3.2) ├── lodash@3.10.1 ├── expand-braces@0.1.1 (array-uniq@1.0.2, array-slice@0.2.3, braces@0.1.5) ├── connect@3.4.0 (utils-merge@1.0.0, parseurl@1.3.0, finalhandler@0.4.0, debug@2.2.0) ├── log4js@0.6.27 (async@0.2.10, underscore@1.8.2, semver@4.3.6, readable-stream@1.0.33) ├── core-js@1.1.4 ├── memoizee@0.3.9 (next-tick@0.2.2, lru-queue@0.1.0, timers-ext@0.1.0, d@0.1.1, event-emitter@0.3.3, es6-weak-map@0.1.4 , es5-ext@0.10.7) ├── body-parser@1.14.0 (bytes@2.1.0, content-type@1.0.1, depd@1.1.0, on-finished@2.3.0, raw-body@2.1.3, debug@2.2.0, ico nv-lite@0.4.11, qs@5.1.0, http-errors@1.3.1, type-is@1.6.8) ├── chokidar@1.1.0 (arrify@1.0.0, path-is-absolute@1.0.0, is-glob@2.0.0, async-each@0.1.6, glob-parent@2.0.0, is-binary- path@1.0.1, readdirp@2.0.0, anymatch@1.3.0) └── socket.io@1.3.7 (has-binary-data@0.1.3, debug@2.1.0, socket.io-parser@2.2.4, socket.io-adapter@0.3.1, engine.io@1.5. 4, socket.io-client@1.3.7)
安装 grunt-karma 插件。
PS C:\study\demo> npm install grunt-karma --save-dev npm WARN package.json app@1.0.0 No description npm WARN package.json app@1.0.0 No repository field. npm WARN package.json app@1.0.0 No README data grunt-karma@0.12.1 node_modules\grunt-karma └── lodash@3.10.1
安装之后,在 node_modules 中实际上有了 grunt, grunt-karma, 以及 karma 三个组件。
继续安装 karma 的插件。
先安装 chrome 的启动器。
PS C:\study\demo> npm install --save-dev karma-chrome-launcher npm WARN package.json demo@1.0.0 No description npm WARN package.json demo@1.0.0 No repository field. npm WARN package.json demo@1.0.0 No README data karma-chrome-launcher@0.2.0 node_modules\karma-chrome-launcher ├── fs-access@1.0.0 (null-check@1.0.0) └── which@1.1.2 (is-absolute@0.1.7)
单元测试 jasmine.
PS C:\study\demo> npm install --save-dev karma-jasmine npm WARN package.json demo@1.0.0 No description npm WARN package.json demo@1.0.0 No repository field. npm WARN package.json demo@1.0.0 No README data npm WARN peerDependencies The peer dependency jasmine-core@* included from karma-jasmine will no npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly. jasmine-core@2.3.4 node_modules\jasmine-core karma-jasmine@0.3.6 node_modules\karma-jasmine
单元测试的输出报表格式 mocha.
PS C:\study\demo> npm install --save-dev karma-mocha-reporter npm WARN package.json demo@1.0.0 No description npm WARN package.json demo@1.0.0 No repository field. npm WARN package.json demo@1.0.0 No README data karma-mocha-reporter@1.1.1 node_modules\karma-mocha-reporter └── chalk@1.1.0 (escape-string-regexp@1.0.3, supports-color@2.0.0, ansi-styles@2.1.0, has-ansi@2.0.0, strip-ansi@3.0.0)
angular 插件
PS C:\study\demo> npm install --save-dev karma-ng-scenario npm WARN package.json demo@1.0.0 No description npm WARN package.json demo@1.0.0 No repository field. npm WARN package.json demo@1.0.0 No README data karma-ng-scenario@0.1.0 node_modules\karma-ng-scenario
requirejs 插件。
PS C:\study\demo> npm install --save-dev karma-requirejs npm WARN package.json demo@1.0.0 No description npm WARN package.json demo@1.0.0 No repository field. npm WARN package.json demo@1.0.0 No README data npm WARN peerDependencies The peer dependency requirejs@~2.1 included from karma-requirejs will no npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly. requirejs@2.1.20 node_modules\requirejs karma-requirejs@0.2.2 node_modules\karma-requirejs
3. 配置
不用版本的 karma 配置会有所不同,这里使用 v0.13 版。karma 的运行配置可以保存在独立的文件中,也可以在 Gruntfile.js 中直接配置,由于 karma 的配置参数较多,建议保存在独立的配置文件中。
这样,我们可以针对不同的测试场景,创建不同的 karma 配置文件,最后通过 grunt 来使用。
karma 配置文件中的 basePath 是一个非常重要的参数,用来表示 karma 配置文件中的其它相对路径所依赖的起点。
如果这是一个对象路径,就会相对于配置文件来定位。
默认是 '', 也就是说配置文件所在的目录就是相对的根目录了。
在 karma 实际运行的时候,这个目录会被自动映射到 /base 之下。
files 中配置可以通过 karma 服务器访问哪些文件,在这里列出的文件,才可以通过 HTTP 访问到。当使用对象方式表示路径的时候,included 表示 karma 是不是需要自动生成一个 script 标记来加载特定的脚本,设置为 false 表示不生成这个标记,而 served 则表示是否可以通过 karma 的网站服务器访问这个文件。
plugins 在 v0.13 中可以不同配置,karma 会自动加载位于 node_modules 中的 karma-* 的 karma 模块。
// Karma configuration // Generated on Tue Sep 15 2015 12:41:55 GMT+0800 (China Standard Time) module.exports = function(config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) basePath: '', // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter // if requirejs used, frameworks: ['jasmine', 'requirejs'], // list of files / patterns to load in the browser files: [ // inclueded, default: true, should the files be included in the browser using <script> tag? // use false if you want to load them manually. eg using require.js // served, default: true, should the files be served by karma's webserver? // watched, default: true, if autowatch is true, all files that have set watched to true will be watched for change { pattern: 'src/**/*.*', included: false, served: true }, { pattern: 'test/**/*_spec.js', included: false, served: true }, //in version 0.13, the item should be last 'test-main.js', ], // list of files to exclude exclude: [ 'src/js/main.js' ], // preprocess matching files before serving them to the browser // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { }, // test results reporter to use // possible values: 'dots', 'progress' // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['mocha'], // web server port port: 9876, // enable / disable colors in the output (reporters and logs) colors: true, // level of logging // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, // enable / disable watching file and executing tests whenever any file changes autoWatch: true, // start these browsers // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ['Chrome'], // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: false, // By default, Karma loads all sibling NPM modules which have a name starting with karma-*. }) }
在配合 requirejs 的时候,我们还需要一个 main.js 文件对 requirejs 进行配置。
在 requirejs 中也有一个 baseUrl 配置参数,这里一定要考虑刚才karma 的 basePath 进行配置,由于在 karma 的网站中,前面又添加了 /base ,所以,现在 requirejs 的 baseUrl 就会变成 /base/src/js 了。
这样,修改了 baseUrl, 我们其它的模块 Id 就不用变化了。
我们希望能够通过 karma 直接加载测试并执行测试,所以,karma 帮助我们生成了一段脚本,从我们网站中的脚本文件中筛选出测试文件,直接加载执行,脚本通过正则表达式 /(spec|test)\.js$/i 来筛选,可以看到,它直接检查脚本文件名中,以 spec.js 或者 test.js 结尾的脚本文件。找到之后,通过 requirejs 配置中的 deps 提前加载并执行。
var allTestFiles = []; var TEST_REGEXP = /(spec|test)\.js$/i; // Get a list of all the test files to include Object.keys(window.__karma__.files).forEach(function(file) { if (TEST_REGEXP.test(file)) { // Normalize paths to RequireJS module names. // If you require sub-dependencies of test files to be loaded as-is (requiring file extension) // then do not normalize the paths // var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, ''); var normalizedTestModule = file; allTestFiles.push(normalizedTestModule); } }); require.config({ // Karma serves files under /base, which is the basePath from your config file baseUrl: '/base/src/js', paths:{ 'angular':'lib/angular.min' }, shim:{ 'angular':{ 'exports': 'angular' } }, // dynamically load all test files deps: allTestFiles, // we have to kickoff jasmine, as it is asynchronous callback: window.__karma__.start }); require(['angular', 'controllers/controllers'], function(angular, controller){ console.log('main.js loaded.'); console.log( controller); }, function(){ console.log("load error"); console.log( arguments); });
4. 测试的写法
比如,我们有一个模块的定义。define([], function(){ return function ($scope){ $scope.name = 'World'; $scope.phones = [ {'name': 'Nexus S', 'snippet': 'Fast just got faster with Nexus S.', 'age':1 }, {'name': 'Motorola XOOM™ with Wi-Fi', 'snippet': 'The Next, Next Generation tablet.', 'age':2 }, {'name': 'MOTOROLA XOOM™', 'snippet': 'The Next, Next Generation tablet.', 'age':3 } ]; $scope.orderProp = 'age'; }; })
测试也是一个模块,一定要在测试的依赖项中,将测试所依赖的模块加载进来。
// use define to load dependency block. define(['controllers/controllers'], function(target) { // regular jasmine test case describe('PhoneCat controllers', function() { describe('PhoneListCtrl', function(){ var scope, ctrl; beforeEach(function(){ scope = {}; // create controller instance ctrl = new target( scope ); }); it('should create "Phone" model with 3 phones.', function(){ expect( scope.phones.length ).toBe( 3 ); }); it(' the name of "Phone" model should be "World".', function(){ expect( scope.name ).toBe('World'); }); it('the age of "Phone" model should be "age",', function(){ expect( scope.orderProp ).toBe( 'age' ); }) }) }); });
执行之后的输出如下:
PS C:\study\photocat> grunt karma Running "karma:unit" (karma) task 16 09 2015 14:38:05.540:WARN [karma]: No captured browser, open http://localhost:9876/ 16 09 2015 14:38:05.555:INFO [karma]: Karma v0.13.9 server started at http://localhost:9876/ 16 09 2015 14:38:05.564:INFO [launcher]: Starting browser Chrome 16 09 2015 14:38:08.382:INFO [Chrome 44.0.2403 (Windows 7 0.0.0)]: Connected on socket IUSWkKhxqSbjN8NzAAAA with id 89877642 Start: hello, jasmine. √ say hello to jasmine. PhoneCat controllers PhoneListCtrl √ should create "Phone" model with 3 phones. √ the name of "Phone" model should be "World". √ the age of "Phone" model should be "age", Finished in 0.013 secs / 0.002 secs SUMMARY: √ 4 tests completed
5. 总结
在配合 requirejs 的时候, karma 路径,requirejs 的路径一定要注意,karma 的服务器将我们的服务内容放在了 /base 之下,我们在使用的时候,必须特别注意这一点。另外,文件名称的大小写问题,在 Windows 系统下大小写不敏感,但是,在 Linux 服务器上,大小写不同将是不同的文件。注意 Karma 服务器中,即使在 Windwos 系统下,也会区分大小写。
在配合 requirejs 时,关键是一定要通过 requirejs 来加载你的模块,而不是直接嵌入带页面中。
http://requirejs.org/docs/errors.html#mismatch
http://icodeit.org/2013/10/using-karma-as-the-javascript-test-runner/
相关文章推荐
- Grunt实现自动化单元测试
- OCR识别的开源分析
- MVP (一) 初次了解,什么是MVP
- 第三方解决键盘遮挡问题总结(IQKeyboardManager)
- java基础--JDBC
- 十二个程序员必备的优质资源推荐
- ThinkPHP中data()方法的使用
- Navigator
- 公告
- qt编译mysql插件
- css中兼容各個IE版本
- HTML在手机端禁止放大缩小
- [转]大型分布式网站架构技术总结
- nginx用户认证
- 解决android 5.0 dialog背景无法透明的问题
- WebLogic配置JNDI数据源
- 互联网的具体分工都有哪些职位?
- 添加黑名单
- 面试(2)-java-se-HashSet和TreeSet
- 爬虫系列4:scrapy技术进阶之多页面爬取