【问题标题】:How to detect if a mocha test is running in node.js?如何检测是否在 node.js 中运行 mocha 测试?
【发布时间】:2015-05-24 20:05:32
【问题描述】:

我想确保如果代码在测试模式下运行,它不会(意外)访问错误的数据库。检测代码当前是否在测试模式下运行的最佳方法是什么?

【问题讨论】:

  • 避免这种情况的最好方法是实际模拟数据层
  • 你在哪里运行你的测试,他们可以访问生产资源?这应该在网络级别解决。生产数据库应该只接受来自生产机器的连接。
  • ...可能不是生产环境。我想确保测试在测试环境中运行。如果没有,我会抛出一个错误。

标签: node.js tdd mocha.js


【解决方案1】:

正如评论中已经提到的,在构建代码时了解测试是不好的做法。我什至在 SO 甚至外面都找不到提到的话题。 但是,我可以想办法检测在测试中启动的事实。 对我来说,mocha 不会将自己添加到global 范围内,而是添加了global.it。 所以你的支票可能是

var isInTest = typeof global.it === 'function';

我建议您确保不要误检测以添加对您最有可能在 node.js 测试中使用的 global.sinonglobal.chai 的检查。

【讨论】:

  • 现在将要构建代码以了解测试。如果有人编写了一个使用部署设置运行的测试,我想抛出一个错误。这个想法是为了保护一些“危险”函数不被错误配置的测试意外调用(比如在生产系统上删除一个表)。
  • 正是那些“故障排除”案例,开发人员往往会忘记他们已连接到真实数据库并运行可能会破坏数据的测试...
  • 另一个用例是在您的代码中有断言,您不介意减慢测试速度,但又无法在生产中使用。
  • 上述解决方案的一个用例:格式化浏览器控制台(在浏览器中运行的 Web 应用程序)与终端输出(单元测试)的调试输出消息。在前一种情况下,console.log(someObject) 更适合使用浏览器的内置 UI 来探索分层数据,而在后者中,console.log(JSON.stringify(someObject)) 更适合输出未截断的变量。
  • 在某些情况下,您想知道它是否是测试,例如应用发送电子邮件而您不希望它在测试中发送它。
【解决方案2】:

根据我的经验,检查 process.argv 是一个不错的方法。

例如,如果我在测试期间console.log(process.argv),我会得到以下信息:

[
  'node',
  '/usr/local/bin/gulp',
  'test',
  '--file',
  'getSSAI.test.unit.js',
  '--bail',
  '--watch'
]

从中您可以看到正在使用 gulp。使用 yargs 可以更轻松地解释这一点。

我非常同意基里尔的观点,一般来说,代码不应该知道它正在被测试的事实(在你的情况下,也许你可以通过构造函数传入你的数据库绑定/连接?),例如记录我可以了解您可能想要检测到这一点的原因。

【讨论】:

  • 我需要检查应用程序是否在测试中运行的唯一原因是检查我没有连接到生产数据库,因为测试会清除数据库。只是纯粹的偏执狂,因为它永远不会发生——但在这个行业的 30 年里,我看到很多事情出错,被宣布为“永远不会发生”。
  • 这里有点悖论。使用您未测试的代码来确保测试代码不会破坏您的生产数据库。同样,我必须向其他阅读此内容的人重新迭代,以便更好地设计您的系统,以便永远不会出现与实时数据库的连接。我得到“那永远不会发生”的前提。然而,同样的规则也适用于你的 Mocha 测试,并且可能意味着你留下了一个糟糕的设计模式恕我直言
【解决方案3】:

最简单的选择是只使用detect-mocha [NPM 包。

var detectMocha = require('detect-mocha');
if(detectMocha()) {
  // doSomethingFancy
}

如果你不想这样做,relevant code 只是

function isMochaRunning(context) {
  return ['afterEach','after','beforeEach','before','describe','it'].every(function(functionName){
    return context[functionName] instanceof Function;
})

其中context 是当前的windowglobal

【讨论】:

    【解决方案4】:

    我同意@Joshua 的回答,他说根据我的经验检查 process.argv 是一个很好的方法。

    所以,我写了一个简单的检测mocha代码。

    const _MOCHA_PATH = new RegExp('(\\\\|/)node_modules\\1mocha\\1bin\\1_mocha$');
    var isMochaRunning = process.argv.findIndex(arg => _MOCHA_PATH.test(arg)) > -1;
    

    【讨论】:

    • 请添加对您的代码如何解决问题的说明
    【解决方案5】:

    在一个没有日志基础设施的小项目中,我使用

    if (process.env.npm_lifecycle_event !== 'test')
      console.error(e);
    

    避免在测试期间记录预期错误,因为它们会干扰测试输出。

    【讨论】:

    • process.env.npm_lifecycle_event 对我来说是 undefined 从 Windows 命令行运行 [全局安装] mocha 时。
    • @SimonEast 我不知道为什么会这样,但三件事似乎很可能:(1)您不是通过 NPM 启动节点应用程序(例如使用 npm start),而是通过调用带有node 的根脚本; (2) 旧版本的节点不提供此变量,或 (3) Windows 上的节点不提供此环境变量。
    猜你喜欢
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2023-03-08
    • 2011-05-04
    • 2016-06-28
    相关资源
    最近更新 更多