组织中型 javascript 客户端应用程序的代码以进行测试
Organizing code of a midly sized javascript client side app for testing
我正在使用 backbone 及其朋友 jquery 和下划线构建一个中等大小的应用程序。我的计划是使用 QunitJS 创建单元测试。
我已经有了该应用程序的概念验证,因此我基本上可以很好地掌握代码的外观,而无需对其进行测试。看起来像这样:
(function() {
// prepare some model
var Query = BackboneModel.extend({});
query = new Query();
// register some events
$('body.something').click(function() {
query.set('key', 'value');
# ...
});
// create some backbone view
var QueryView = Backbone.View.extend({...})
// init backbone view
query.view = new QueryView();
// add some plumbing here ...
// and so on...
})();
否则说:
- 我将模块包装在函数中以避免污染
- Class声明和class使用交错
- 事件注册与其余代码交织在一起
- 模块的全局变量在模块内部重用
现在我需要测试一下。问题是,我认为,主要是关于事件注册和管道。
我的计划是将代码包装在函数中并导出我要测试的每个函数和对象。代码将如下所示:
var app = (function() {
var app = {}
// prepare some model
var Query = BackboneModel.extend({});
app.query = new Query();
// register some events
app.registerEvent = function() {
$('body.something').click(function() {
query.set('key', 'value');
# ...
});
};
app.registerEvent(); // XXX: call immediatly
// create some backbone view
app.QueryView = Backbone.View.extend({...})
// init backbone view
app.query.view = new QueryView();
// add some plumbing here ...
// wrapped in function with correct arguments and call it immediatly
// and so on...
// ...
return app;
})();
这是我第一次需要在 javascript 中为此类应用程序编写测试,所以我想知道我使代码可测试的方法是否正确或是否可以改进。例如,在我看来,将事件注册包装在没有参数的函数中并立即调用它们似乎很愚蠢。
有javascript方法吗?
所以我找到了一种极好的方法来测试私有函数,同时保持我的生产代码干净。我不确定您是否使用任何构建系统,如 G运行t 或 Gulp,但如果您愿意接受它,您可以这样做:
//has a dependency of 'test' causing it to run testing suite first
gulp.task('js', ['test'], function() {
return gulp.src(source)
.pipe(plumber())
//create sourcemaps so console errors point to original file
.pipe(sourcemaps.init())
//strip out any code between comments
.pipe(stripCode({
start_comment: 'start-test',
end_comment: 'end-test'
}))
//combine all separatefiles into one
.pipe(concatenate('mimic.min.js'))
//minify and mangle
.pipe(uglify())
.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('dist/js'));
});
文件可能如下所示:
var app = (function () {
function somePrivateFunction () {}
function someotherPrivateFunction () {}
var app = {
publicFunction: function(){}
publicVar: publicVar
}
/* start-test */
app.test = {
testableFunction: somePrivateFunction
}
/* end-test */
}());
在测试 运行 之后,测试注释之间的所有内容都会被删除,因此生产代码是干净的。 G运行t 有一个这样的版本,我假设任何自动构建系统都可以做同样的事情。您甚至可以设置一个监视任务,以便 运行 对每次保存进行测试。否则,您必须在部署之前手动删除导出的测试对象。
在 Backbone 的情况下,只需将测试对象附加到模块并在测试中引用该对象。或者如果你真的想分离它,将对象设置在全局范围内。 window.testObject = { //list of objects and methods to test... };
并在部署前删除该代码。
基本上我所做的是避免在我想测试的库中进行任何调用。所以一切都包装在一个函数中并导出。
然后我还有另外两个文件,一个是 main.js
,我在其中进行管道连接,应该使用 selenium 的集成测试进行测试,另一个是 tests.js
,它进行单元测试。
我正在使用 backbone 及其朋友 jquery 和下划线构建一个中等大小的应用程序。我的计划是使用 QunitJS 创建单元测试。
我已经有了该应用程序的概念验证,因此我基本上可以很好地掌握代码的外观,而无需对其进行测试。看起来像这样:
(function() {
// prepare some model
var Query = BackboneModel.extend({});
query = new Query();
// register some events
$('body.something').click(function() {
query.set('key', 'value');
# ...
});
// create some backbone view
var QueryView = Backbone.View.extend({...})
// init backbone view
query.view = new QueryView();
// add some plumbing here ...
// and so on...
})();
否则说:
- 我将模块包装在函数中以避免污染
- Class声明和class使用交错
- 事件注册与其余代码交织在一起
- 模块的全局变量在模块内部重用
现在我需要测试一下。问题是,我认为,主要是关于事件注册和管道。
我的计划是将代码包装在函数中并导出我要测试的每个函数和对象。代码将如下所示:
var app = (function() {
var app = {}
// prepare some model
var Query = BackboneModel.extend({});
app.query = new Query();
// register some events
app.registerEvent = function() {
$('body.something').click(function() {
query.set('key', 'value');
# ...
});
};
app.registerEvent(); // XXX: call immediatly
// create some backbone view
app.QueryView = Backbone.View.extend({...})
// init backbone view
app.query.view = new QueryView();
// add some plumbing here ...
// wrapped in function with correct arguments and call it immediatly
// and so on...
// ...
return app;
})();
这是我第一次需要在 javascript 中为此类应用程序编写测试,所以我想知道我使代码可测试的方法是否正确或是否可以改进。例如,在我看来,将事件注册包装在没有参数的函数中并立即调用它们似乎很愚蠢。
有javascript方法吗?
所以我找到了一种极好的方法来测试私有函数,同时保持我的生产代码干净。我不确定您是否使用任何构建系统,如 G运行t 或 Gulp,但如果您愿意接受它,您可以这样做:
//has a dependency of 'test' causing it to run testing suite first
gulp.task('js', ['test'], function() {
return gulp.src(source)
.pipe(plumber())
//create sourcemaps so console errors point to original file
.pipe(sourcemaps.init())
//strip out any code between comments
.pipe(stripCode({
start_comment: 'start-test',
end_comment: 'end-test'
}))
//combine all separatefiles into one
.pipe(concatenate('mimic.min.js'))
//minify and mangle
.pipe(uglify())
.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('dist/js'));
});
文件可能如下所示:
var app = (function () {
function somePrivateFunction () {}
function someotherPrivateFunction () {}
var app = {
publicFunction: function(){}
publicVar: publicVar
}
/* start-test */
app.test = {
testableFunction: somePrivateFunction
}
/* end-test */
}());
在测试 运行 之后,测试注释之间的所有内容都会被删除,因此生产代码是干净的。 G运行t 有一个这样的版本,我假设任何自动构建系统都可以做同样的事情。您甚至可以设置一个监视任务,以便 运行 对每次保存进行测试。否则,您必须在部署之前手动删除导出的测试对象。
在 Backbone 的情况下,只需将测试对象附加到模块并在测试中引用该对象。或者如果你真的想分离它,将对象设置在全局范围内。 window.testObject = { //list of objects and methods to test... };
并在部署前删除该代码。
基本上我所做的是避免在我想测试的库中进行任何调用。所以一切都包装在一个函数中并导出。
然后我还有另外两个文件,一个是 main.js
,我在其中进行管道连接,应该使用 selenium 的集成测试进行测试,另一个是 tests.js
,它进行单元测试。