Mocha: 第一个单元测试总是比其他单元测试慢。

创建于 2017-11-10  ·  3评论  ·  资料来源: mochajs/mocha

先决条件

  • [x] 通过交叉引用带有common mistake标签的问题,检查您的问题是否尚未提交
  • [x] 在没有 Mocha 的情况下使用相同的环境和/或转译器配置检查了下一代 ES 问题和语法问题,以确保它不仅仅是相关环境中实际不支持的功能或代码中的错误.
  • [x] '冒烟测试' 通过在真实测试套件之外运行要测试的代码来更好地了解问题是出在被测代码、您对 Mocha 的使用还是 Mocha 本身
  • [x] 确保本地和全局安装的 Mocha 版本之间没有差异。 您可以通过以下方式找到它们:
    node node_modules/.bin/mocha --version (本地)和mocha --version (全球)。 我们建议避免使用全局安装的 Mocha。

描述

出于某种原因,我的测试套件的第一个单元测试总是比其他单元测试慢。 在我的控制台中执行测试时,我得到如下信息:

√ unit test A (483ms)
√ unit test B

但是在代码中,如果我将单元测试 B 更改为单元测试 A 的上方,我会得到:
√ unit test B (470ms)
√ unit test A

由于某种原因,第一个单元测试总是变慢,因此我认为,不是我的代码变慢的原因,而是 Mocha 中的某些东西。 同时,我还有其他测试套件正在测试其他代码并且工作正常,所以我很困惑。 也许不是摩卡,但由于不确定,我需要问你是否知道会发生什么。

测试是这样的:

let target = require('...');

describe('Module of unit tests', function () {
  this.timeout(1000);
  before(function () {
    ...
    target = proxyquire('...', {
      'node-chartist': sinon.stub().resolves('...'),
      'ws': function(){
        return {
          'close': function(){ /*Do nothing*/ },
          'send': function(){ /*Do nothing*/ },
          'on': function(arg, callback){
            ...
          }
        };
      }
    });
  });

  //Warning happens here
  it('unit test A', function () {
    ...
    target();
    ...
  });

  //If this unit test goes above unit test A, this will be the one to get the warning.
  it('unit test B', function () {
    ...
    target();
    ...
  });
})

重现步骤

我试图在其他项目中复制但没有成功,所以我怀疑你能做到,但我正在做的是:

1) 使用上面的单元测试 A 执行测试套装。
2) 使用上面的单元测试 B 执行测试套装。

预期行为: [您预期会发生什么]
在这两种情况下都不会收到有关时间的任何警告。

实际行为: [实际发生的情况]
第一个单元测试总是会收到有关时间的警告。

重现频率: [它重现的时间百分比是多少?]
大约 90% 的时间。

版本

节点 v6.11.4
npm 3.10.10
摩卡4.0.1
诗意4.1.2
柴 3.5.0
代理查询 1.8.0

附加信息

我使用 fiddler 确保在执行单元测试时,没有向外部发出任何网络请求,以确保延迟不是由任何网络请求引起的。

我还调试了单元测试正在测试的代码,无论如何我真的看不出有任何延迟的原因。

最有用的评论

嗨 ScottFreeCode,

感谢您的回复,它非常有用。 问题的发生是因为我正在使用 proxyquire 制作一些存根,并且默认情况下,即使在存根时也会加载 npm 模块。 就我而言,我有一个名为 node-chartist 的模块,该模块在第一次单元测试期间被加载,这就是它比其他模块慢的原因。

为了解决这个问题,我不得不使用 proxyquire 的 noCallThru() 方法,它使 proxyquire 不加载任何原始依赖项。

谢谢您的帮助。

亲切的问候,

丹尼尔·塞朗

所有3条评论

值得尝试的一件事是将两个测试共有的所有内容(除了任何断言)复制到before挂钩中,以查看在另一个地方简单地运行相同类型的东西是否会使其首先运行任何类型速度较慢,而不是专门测试第一次。

有可能代码,即使它通常不一定很慢,第一次初始化一些东西,然后以某种方式保存(例如 Node 的require缓存,或来自磁盘的文件系统级数据缓存,或者一些库代码中内置的重用优化),或者 JavaScript 引擎在代码运行一次后在代码中寻找优化,或者类似的东西。 您也可以将它完全放在测试套件之外,尽管这不太可能起作用 - 对于几种类型的缓存,在加载测试文件和实际运行此特定文件的测试之间的某个地方缓存用尽的可能性更大(另一方面,如果before钩子起作用而在测试套件之外没有起作用,那可能会缩小负责哪种缓存或优化的范围......)。

(在完全不同的情况下,比解决方案更多的解决方法 - 对于任何只想抑制时间警告的人,有slow选项与timeout选项一起使用。)

嗨 ScottFreeCode,

感谢您的回复,它非常有用。 问题的发生是因为我正在使用 proxyquire 制作一些存根,并且默认情况下,即使在存根时也会加载 npm 模块。 就我而言,我有一个名为 node-chartist 的模块,该模块在第一次单元测试期间被加载,这就是它比其他模块慢的原因。

为了解决这个问题,我不得不使用 proxyquire 的 noCallThru() 方法,它使 proxyquire 不加载任何原始依赖项。

谢谢您的帮助。

亲切的问候,

丹尼尔·塞朗

很高兴我能帮助你弄清楚这一点!让我们知道您是否还有其他需要。

此页面是否有帮助?
0 / 5 - 0 等级