我以为我会发布这个,因为我偶然发现了一会儿,然后注意到发生了什么。我有一个测试套件,它使用CouchDB作为其记录/记录数据库。我发现你可以在实习生中编写自定义记者,所以我想我可以移动很多我的手册'recordSuccess()'/'recordFailure()'调用我的测试脚本,然后调用自定义报告器来响应测试通过和失败事件
我的主要测试脚本仍然想要做一些couchdb交互,所以我将couchdb连接和报告功能分解为一个模块,然后尝试从主测试脚本和自定义报告模块中使用该模块。 / p>
我发现couchdb辅助模块实例化了两次。这违背了期望AMD / RequireJS require()只执行一次模块,并在下次需要模块时缓存结果以供使用。如果我在其主体代码中放置一个“调试器”语句,它显然会被执行两次。对我来说,结果是,当记者调用时,couchdb引用是未定义的。
目录结构:
runTest.js # helper script to run intern test from this dir
src/MainTest.js
src/CouchHelper.js
src/CouchDBReporter.js
src/intern.js # intern config
runTest.js
node node_modules/.bin/intern-client config=src/intern suites=mypackage/WINTest --envConfig=src/test/dev.json
即。 MainTest.js:
define([ 'CouchHelper' ], function (CouchHelper) {
.. test startup ..
CouchHelper.connect(username, password, etc);
CouchDBReporter.js:
define([ 'CouchHelper' ], function (CouchHelper) {
return {
'/test/fail': function (test) {
// Presume the couchdb is connected at this point
CouchHelper.recordFailure(test);
}
}
intern.js:
... blah blah ..
loader: {
// Packages that should be registered with the loader in each testing environment
packages: [
'node',
'nedb',
'nodemailer',
{ 'mypackage', 'src' }
],
reporters: [ 'console', 'src/CouchDBReporter' ]
CouchHelper.js:
define([
'intern/dojo/node!node-couchdb'
], function (Couchdb) {
debugger; // this is hit twice
var instance = 0;
function CouchHelper() {
this.couchdb = undefined;
this.instance = instance++;
console.log('Created instance ' + this.instance);
}
CouchHelper.prototype = {
connect: function () { this.couchdb = Couchdb.connect(blah); },
recordFailure: function (test) { this.couchdb.insert(blah); }
}
}
启动时,控制台会记录:
Created instance 0
Created instance 0
当记者调用recordFailure时,它会调用CouchHelper的不同实例而不是名为connect()的MainTest.js文件..所以this.couchdb未定义,脚本崩溃。我可以在MainTest.js中调用recordSuccess / recordFailure,并且this.couchdb在CouchHelper中有效,但是从CouchDBReporter中,CouchHelper实例明显不同。
是否需要这种行为?如果是这样,在主要测试代码和自定义报告器中的代码之间共享数据和资源的推荐方法是什么?我看到在3.0中,记者配置可以采取一个可能有助于缓解这个问题的对象,但感觉就像人们必须以编程方式实例化报告者而不是在配置中定义它。
尼克
答案 0 :(得分:1)
正如Colin所说,答案的路径在于我的加载器地图配置。这意味着我在命令行上引用为config
的intern.js文件具有loader
部分,其中可以定义到AMD模块的路径映射(请参阅https://theintern.github.io/intern/#option-loader)。通常我只是定义一个包名列表,例如我知道我的测试需要nedb,nodemailer和我自己的src包:
loader: {
packages: [ 'node', 'nedb', 'nodemailer', 'src' ]
}
出于某种原因,我已将src
包定义为名称mypackage
可用:
loader: {
packages: [ 'node', 'nedb', 'nodemailer',
{ name: 'mypackage', location: 'src' }
]
}
我没有充分的理由这样做。然后我指定我的自定义记者由实习生使用' src'包名称:
intern.js:
reporters: [ 'console', 'src/CouchDBReporter' ]
而且,这是一个棘手的问题,我以两种不同的方式引用了我的辅助模块CouchHelper
,但两次使用相对模块路径./CouchHelper
:
MainTest.js:
require([
'./CouchHelper',
...
], ...
CouchDBReporter.js:
require([
'./CouchHelper',
...
], ...
在命令行中,您猜对了,将测试指定为mypackage/MainTest.js
。这与src/CouchDBReporter
intern.js
部分中reporter
的规范相冲突。
结果是mypackage/MainTest.js
需要./CouchHelper
解析为mypackage/CouchHelper
,src/CouchDBReporter
需要./CouchHelper
,其解析为src/CouchHelper
。这样就加载了CouchHelper模块代码两次,使用AMD样式加载器来保证模块只加载一次。
它确实是AMD模块路径中的一个很好的教训,也是使用相对路径的一个含义。