代码之家  ›  专栏  ›  技术社区  ›  Neek

实习生自定义报告器依赖项作为不同的模块实例加载

  •  0
  • Neek  · 技术社区  · 10 年前

    我想我会在发现发生了什么事情之前发布这篇文章。我有一个使用CouchDB作为日志/记录数据库的测试套件。我发现你可以在实习生中编写自定义报告器,所以我想我可以将很多手动的“recordSuccess()”/“recordFailure()”调用从测试脚本中移出,并转换为响应测试通过和失败事件的自定义报告器。

    我的主测试脚本仍然希望进行一点couchdb交互,因此我将couchdb连接和报告函数分解为一个模块,然后尝试从主测试脚本和自定义报告器模块中使用该模块。

    我发现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
    

    运行测试.js

    node node_modules/.bin/intern-client config=src/intern suites=mypackage/WINTest --envConfig=src/test/dev.json 
    

    i、 e.主测试.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);
        }
      }
    

    内部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,而这个.couchdb在CouchHelper中是有效的,但在CouchDBReporter中,CouchHelp器实例明显不同。

    这种行为是预期的吗?如果是,在主测试代码和自定义报告器中的代码之间共享数据和资源的推荐方法是什么?我看到,在3.0中,报告器配置可以接受一个可能有助于缓解这个问题的对象,但感觉必须以编程方式实例化报告器,而不是在配置中定义它。

    刻痕

    1 回复  |  直到 10 年前
        1
  •  1
  •   Neek    10 年前

    正如科林所建议的,答案的路径在我的加载器映射配置中。这意味着我的intern.js文件,引用为 config 在命令行上,具有 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”包名指定我的自定义报告程序由实习生加载:

    内部js:

    reporters: [ 'console', 'src/CouchDBReporter' ]
    

    还有一个棘手的问题,我引用了我的助手模块, CouchHelper ,以两种不同的方式,但都使用相对模块路径 ./CouchHelper :

    主测试.js:

    require([
        './CouchHelper',
        ...
    ], ...
    

    CouchDBReporter.js:

    要求([
    './CouchHelper’,
    ...
    ], ...
    

    您猜到了,在命令行上,指定测试运行为 mypackage/MainTest.js 。这与我的规范冲突 src/CouchDBReporter 在里面 intern.js reporter 部分

    结果是 mypackage/MainTest.js 必修的 ./沙发助手 其解析为 mypackage/CouchHelper src/CouchDBReporter 必修的 ./沙发助手 ,解析为 src/CouchHelper 。这两次加载了CouchHelper模块代码,解决了AMD风格加载程序通常保证模块只加载一次的问题。

    这当然是AMD模块路径的一个很好的教训,也是使用相对路径的一种暗示。