独立于网络浏览器的单元测试 JavaScript
Unit testing web-browser independent JavaScript
我的客户端 JavaScript 不以任何方式与 DOM 或网络浏览器交互。我想在 Travis-CI 中对这段代码(这只是一个花哨的 database/buffer)的功能进行单元测试,而无需启动网络浏览器。命令行 JavaScript 让我觉得我需要 node.js。我查看了各种单元测试库并决定使用 Mocha,因为它的简单性,但是使用基于 node.js 的库测试基于浏览器的 module/class 似乎过于困难。
具体来说,我想测试这个(简化版)浏览器JavaScript有效代码:
// I need this NameSpace to organise my code and isolate from other code
var Nengo = {};
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
for(var i = 0; i < this.data.length; i++){
this.data[i].push(row[i+1]);
}
}
当我尝试在 Node.js 中进行测试时,我无法正确导入 Nengo 命名空间的概念。这个测试连运行:
都做不到
// get the datastore code from the folder below
require("../simple_data")
var assert = require("assert")
describe("DataStore", function() {
var data_store = new Nengo.DataStore(2);
it("accepts data", function() {
data_store.push([0.0, 1.1, 1.2])
assert.deepEqual(data_store.data, [[1.1], [1.2]])
});
});
失败并出现以下错误:
/home/saubin/javascript_test/test/simple_test.js:5
var data_store = new Nengo.DataStore(2);
^
ReferenceError: Nengo is not defined
at Suite.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:5:22)
at context.describe.context.context (/usr/local/lib/node_modules/mocha/lib/interfaces/bdd.js:49:10)
at Object.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:4:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at /usr/local/lib/node_modules/mocha/lib/mocha.js:192:27
at Array.forEach (native)
at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:189:14)
at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:422:31)
at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:398:16)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:935:3
我想到的解决这个问题的一种方法是放弃节点并将测试结果输出到无头浏览器的 DOM 并获取结果,但这似乎有很多额外的开销。我可以更改我的代码结构以与 Node.js 兼容吗?由于缺乏该领域的知识,是否还有其他一些我没有看到的解决方案?
您可以使您的代码 "node.js-aware" 将全局定义放入实际的全局上下文中,同时仍然与浏览器环境保持完全兼容:
if (typeof window !== "undefined") {
// in browser, define global to be an alias for window
// so global can be used to refer to the global namespace in
// both the browser and node.js
var global = window;
}
global.Nengo = {};
(function() {
var Nengo = global.Nengo;
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
this.data.push(row.slice(1));
}
})();
然后,请记住任何全局定义都必须显式分配给 global
命名空间。在 node.js 中,这会将它们分配给 node.js 中的实际 global
名称空间。在浏览器中,这会将它们分配给 window
对象,该对象是浏览器中的全局命名空间。
尽管@jfrien00 的回答在技术上是正确的,但我后来想出了另一个答案。
首先,我需要重构我的 JavaScript 代码以在 DataStore
文件之外声明我的命名空间。然后我将 Nengo 全局变量声明为 jfriend00 描述 global.Nengo = {};
,但仅在我的 Mocha 测试文件中。
这样,当我 运行 在我的网络浏览器中进行单元测试时,我的代码会按预期进行测试。
我的客户端 JavaScript 不以任何方式与 DOM 或网络浏览器交互。我想在 Travis-CI 中对这段代码(这只是一个花哨的 database/buffer)的功能进行单元测试,而无需启动网络浏览器。命令行 JavaScript 让我觉得我需要 node.js。我查看了各种单元测试库并决定使用 Mocha,因为它的简单性,但是使用基于 node.js 的库测试基于浏览器的 module/class 似乎过于困难。
具体来说,我想测试这个(简化版)浏览器JavaScript有效代码:
// I need this NameSpace to organise my code and isolate from other code
var Nengo = {};
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
for(var i = 0; i < this.data.length; i++){
this.data[i].push(row[i+1]);
}
}
当我尝试在 Node.js 中进行测试时,我无法正确导入 Nengo 命名空间的概念。这个测试连运行:
都做不到// get the datastore code from the folder below
require("../simple_data")
var assert = require("assert")
describe("DataStore", function() {
var data_store = new Nengo.DataStore(2);
it("accepts data", function() {
data_store.push([0.0, 1.1, 1.2])
assert.deepEqual(data_store.data, [[1.1], [1.2]])
});
});
失败并出现以下错误:
/home/saubin/javascript_test/test/simple_test.js:5
var data_store = new Nengo.DataStore(2);
^
ReferenceError: Nengo is not defined
at Suite.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:5:22)
at context.describe.context.context (/usr/local/lib/node_modules/mocha/lib/interfaces/bdd.js:49:10)
at Object.<anonymous> (/home/saubin/javascript_test/test/simple_test.js:4:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at /usr/local/lib/node_modules/mocha/lib/mocha.js:192:27
at Array.forEach (native)
at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:189:14)
at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:422:31)
at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:398:16)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:935:3
我想到的解决这个问题的一种方法是放弃节点并将测试结果输出到无头浏览器的 DOM 并获取结果,但这似乎有很多额外的开销。我可以更改我的代码结构以与 Node.js 兼容吗?由于缺乏该领域的知识,是否还有其他一些我没有看到的解决方案?
您可以使您的代码 "node.js-aware" 将全局定义放入实际的全局上下文中,同时仍然与浏览器环境保持完全兼容:
if (typeof window !== "undefined") {
// in browser, define global to be an alias for window
// so global can be used to refer to the global namespace in
// both the browser and node.js
var global = window;
}
global.Nengo = {};
(function() {
var Nengo = global.Nengo;
Nengo.DataStore = function(dims) {
this.times = [];
this.data = [];
for (var i=0; i < dims; i++) {
this.data.push([]);
}
}
Nengo.DataStore.prototype.push = function(row) {
this.times.push(row[0]);
this.data.push(row.slice(1));
}
})();
然后,请记住任何全局定义都必须显式分配给 global
命名空间。在 node.js 中,这会将它们分配给 node.js 中的实际 global
名称空间。在浏览器中,这会将它们分配给 window
对象,该对象是浏览器中的全局命名空间。
尽管@jfrien00 的回答在技术上是正确的,但我后来想出了另一个答案。
首先,我需要重构我的 JavaScript 代码以在 DataStore
文件之外声明我的命名空间。然后我将 Nengo 全局变量声明为 jfriend00 描述 global.Nengo = {};
,但仅在我的 Mocha 测试文件中。
这样,当我 运行 在我的网络浏览器中进行单元测试时,我的代码会按预期进行测试。