这里的问题比较冗长,所以请耐心等待。
我一直在尝试将单元测试添加到我们的客户端代码中一段时间,最后还是花时间去做。我们现在使用AMD(requirejs),但这也是我正在探索的问题。所以过去几天我一直致力于为我们当前的设置准备一些测试基础设施,并使用phantomJS,Karma和Jasmine从终端进行测试。我在渲染Kendo组件时遇到了问题,所以在我深入研究之前,我想问一下是否有人知道是否:
一些背景知识: 我们所有的库脚本都在本地加载requirejs。 jQuery和kendoui是通过脚本标签静态加载的(与全局化通过requirejs进行操作时无法正常工作)。
当我尝试测试包装Kendo组件的Marionette View时,我得到“$ el.kendoGrid”不是一个函数。然而,“kendo”全局附加到窗口。
karma.conf.js:
// Karma configuration
// Generated on Wed Dec 28 2016 13:38:24 GMT-0600 (Central Standard Time)
module.exports = function (config) {
"use strict";
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
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
// Loads jQuery and kendoui statically via a script tag so the globals are available as expected by our
// source JavaScript files.
'web-libs-common/src/main/resources/META-INF/resources/static/js/lib/jquery/jquery.js',
'web-libs-common/src/main/resources/META-INF/resources/static/js/lib/kendoui/kendo.all.js',
// Load requirejs and its karma adapter after making the above scripts available.
'node_modules/requirejs/require.js',
'node_modules/karma-requirejs/lib/adapter.js',
//The following patterns make the files available to be loaded by requireJS.
{pattern: 'healthems-web/test/js/**/*.js', included: false}, //Make the test files available, but do not load.
//Make the source files available, but do not load
{pattern: 'healthems-web/src/main/resources/META-INF/resources/static/js/**/*.js', included: false},
//Make the library files available but do not load.
{
pattern: 'web-libs-common/src/main/resources/META-INF/resources/static/js/lib/**/*.js',
included: false
},
//Make the html templates available but do not load.
{pattern: 'healthems-web/src/main/resources/META-INF/resources/static/html/**/*.html', included: false},
//Make the test_utils directory available, but do not load.
{pattern: 'test_utils/*.js', included: false},
{pattern: 'node_modules/squirejs/src/Squire.js', included: false},
'test-main.js'
],
// list of files to exclude
exclude: [
],
// 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: ['spec'],
// 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_ERROR,
// 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: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
});
};
测试main.js:
"use strict";
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, '');
allTestFiles.push(normalizedTestModule);
}
});
var baseLibPath = "web-libs-common/src/main/resources/META-INF/resources/static/js/";
var baseAppPath = "healthems-web/src/main/resources/META-INF/resources/static/js/";
var baseTemplatePath = "healthems-web/src/main/resources/META-INF/resources/static/";
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: '/base',
map: {
'*': {
underscore: 'lodash'
}
},
paths: {
'app': baseAppPath + 'app',
'backbone': baseLibPath + 'lib/backbonejs/backbone',
'backbone.marionette': baseLibPath + 'lib/backbonejs/backbone.marionette',
'backbone.paginator': baseLibPath + 'lib/backbonejs/backbone.paginator',
'backbone.validation': baseLibPath + 'lib/backbonejs/backbone.validation',
'format': baseAppPath + 'format',
'jquery.ui': baseLibPath + 'lib/jquery/jquery.ui',
'jquery.waypoints': baseLibPath + 'lib/jquery/jquery.waypoints',
'jquery.waypoints.sticky': baseLibPath + 'lib/jquery/jquery.waypoints.sticky',
'kendoui': baseLibPath + 'lib/kendoui/kendo.all',
'json3': baseLibPath + 'lib/json3',
'jstz': baseLibPath + 'lib/jstz',
'jszip': baseLibPath + 'lib/kendoui/jszip.min',
'jquery': baseLibPath + 'lib/jquery/jquery',
'lodash': baseLibPath + 'lib/lodash',
'mocks': 'test_utils/defaultMocks',
'moment': baseLibPath + 'lib/momentjs/moment-with-locales',
'moment.timezone': baseLibPath + 'lib/momentjs/moment-timezone-with-data',
'rsvp': baseLibPath + 'lib/rsvp',
'sockjs': baseLibPath + 'lib/sockjs',
'spin': baseLibPath + 'lib/spin',
'stomp': baseLibPath + 'lib/stomp',
'Squire': 'node_modules/squirejs/src/Squire',
'template': baseTemplatePath + 'html/template',
'text': baseLibPath + 'lib/requirejs-text/text',
'util': baseAppPath + 'util',
'sprintf': baseLibPath + 'lib/sprintf'
},
shim: {
'jstz': {
exports: 'jstz'
},
'jquery.waypoints': {
deps: ['jquery'],
exports: 'Waypoint'
},
'jquery.waypoints.sticky': {
deps: ['jquery.waypoints'],
exports: 'Waypoint.Sticky'
},
'spin': {
exports: 'Spinner'
},
'stomp': {
exports: 'Stomp'
},
'sprintf': {
exports: 'sprintf'
}
}
// dynamically load all test files
//deps: allTestFiles,
// we have to kickoff jasmine, as it is asynchronous
//callback: window.__karma__.start
});
require(allTestFiles, function () {
window.__karma__.start();
});
我们的主应用程序requirejs config:
global.requirejs.config({
map: {
'*': {
underscore: 'lodash'
}
},
paths: {
'backbone': 'lib/backbonejs/backbone',
'backbone.marionette': 'lib/backbonejs/backbone.marionette',
'backbone.paginator': 'lib/backbonejs/backbone.paginator',
'backbone.validation': 'lib/backbonejs/backbone.validation',
'jquery.ui': 'lib/jquery/jquery.ui',
'jquery.waypoints': 'lib/jquery/jquery.waypoints',
'jquery.waypoints.sticky': 'lib/jquery/jquery.waypoints.sticky',
'json3': 'lib/json3',
'jstz': 'lib/jstz',
'jszip': 'lib/kendoui/jszip.min',
'lodash': 'lib/lodash',
'moment': 'lib/momentjs/moment-with-locales',
'moment.timezone': 'lib/momentjs/moment-timezone-with-data',
'rsvp': 'lib/rsvp',
'sockjs': 'lib/sockjs',
'spin': 'lib/spin',
'stomp': 'lib/stomp',
'template': '../html/template',
'text': 'lib/requirejs-text/text',
'sprintf': 'lib/sprintf'
},
shim: {
'jstz': {
exports: 'jstz'
},
'jquery.waypoints': {
deps: ['jquery'],
exports: 'Waypoint'
},
'jquery.waypoints.sticky': {
deps: ['jquery.waypoints'],
exports: 'Waypoint.Sticky'
},
'spin': {
exports: 'Spinner'
},
'stomp': {
exports: 'Stomp'
},
'sprintf': {
exports: 'sprintf'
}
}
});
define('jquery', [], function() {
return window.jQuery;
});
define('kendoui', [], function() {
window.kendo.culture("en-US");
window.kendo.culture().numberFormat.currency.pattern[0] = "-$n";
return window.kendo;
});
我对节点非常陌生,对karma,jasmine和phantomJS的经验有限,所以我一直在背上徘徊一段时间,现在试图解决这个问题,所以任何帮助都会非常好。谢谢!