如何让Mocha加载一个定义全局钩子或实用程序的helper.js文件?

Zla*_*tko 39 javascript mocha.js node.js

我有一个名为的文件test/helper.js,用于在我的Node.js应用程序上运行Mocha测试.我的测试结构如下:

test/
test/helper.js    # global before/after
test/api/sometest.spec.js
test/models/somemodel.spec.js
... more here
Run Code Online (Sandbox Code Playgroud)

helper.js必须加载该文件,因为它包含我的测试套件的全局钩子.当我运行Mocha来执行整个测试套件时:

mocha --recursive test/
Run Code Online (Sandbox Code Playgroud)

helper.js文件在我的测试加载和我的before钩被按预期执行.

但是,当我只运行一个特定的测试时,helper.js在测试之前没有加载.这是我运行它的方式:

mocha test/api/sometest.spec.js
Run Code Online (Sandbox Code Playgroud)

没有全球before叫,甚至没有console.log('I WAS HERE');.

那么我怎样才能让Mocha 始终加载我的helper.js文件?

Lou*_*uis 23

Mocha没有任何名为的特殊文件的概念 helper.js会在其他文件之前加载.

当你运行你所要做的工作mocha --recursive,因为在摩卡的顺序发生加载文件.因为helper.js比其他文件高一级,所以首先加载它.当您为Mocha指定单个文件时,Mocha只会加载此文件,并且正如您所发现的那样helper.js文件根本没有加载.

所以,你想要做的是加载的文件,以便将设置顶层("全球")挂钩(例如before,after等).选项:

  1. 您可以通过编程方式使用Mocha并按所需顺序将其提供给文件.

  2. 你可以强迫自己始终指定命令行上的帮助文件,第一你列出任何其他文件之前.(我不会这样做,但有可能.)

  3. 另一种选择是组织你的套房,就像我在这个答案中详述的那样.基本上,您有一个"顶级"文件,可以将套件的其余部分加载到其中.使用此方法,您将无法在单个文件上运行Mocha,但您可以使用它--grep来选择正在运行的内容.

无法使用该-r选项.它在运行套件之前加载模块,但不幸的是,加载的模块无法访问Mocha为测试提供的任何测试接口,因此无法设置挂钩.


ara*_*y12 17

首先,我肯定会使用,mocha.opts这样您就不必每次都包含您想要的选项.正如所指出的,一种选择是使用--grep,但我并不是个人的忠实粉丝.它要求您以过于简单的方式命名所有内容.如果before钩子不是异步,你可以--require在你的mocha.opts.例如

#mocha.opts
--recursive
--require test/helpers.js
Run Code Online (Sandbox Code Playgroud)

听起来这对你不起作用,因为你也需要全局after钩子.我所做的就是每次都调用完整的测试套件,但如果我正处于测试阶段,只想测试一个套件,甚至是一个特定的测试,我会使用排他性功能,only https:// mochajs. org /#exclusive-tests.您可以制作它it.only('...或者describe.only('...如果您这样做,它会查看所有测试并设置与您的完整测试工具完全相同,但只执行您指定的测试或套件.

现在你可以包含那些全局钩子没问题.@Louis提到你helpers.js只是在正确的顺序加载.事实并非如此.如果将任何挂钩放在describe块之外,它将自动成为全局挂钩.这可以通过将其放入自己的文件中来实现

// helpers.js
before(function() { console.log('testing...'); });
Run Code Online (Sandbox Code Playgroud)

或在测试文件中

// some.spec.js
before(function() { console.log('testing...'); });

describe('Something', function() {
  it('will be tested', function() {
  ...
  });
});
Run Code Online (Sandbox Code Playgroud)

显然,我认为将它放在自己的文件中更清晰.(我叫它hooks.js).重点是,这不是文件加载顺序的结果.

只有一个问题对其他人来说可能是显而易见的,但我曾经简单地挣扎 - 没有放在一个describe区块中的钩子都是全局的.它们不是特定于目录的.因此,如果您复制helpers.js到测试的子目录中,before并且after钩子现在将触发两次.此外,如果您beforeEach在其中放置一个钩子,它将在每次测试之前触发,而不仅仅是该目录中的那些测试.

无论如何,我知道这篇文章有点陈旧,但希望这会帮助其他人遇到类似的问题.


Pau*_*ond 16

我所做的是创建一个test/test_helper.js文件,它导出我创建的所有帮助程序:

// test/test_helper.js    
module.exports = {
    MyHelper: require('./helpers/MyHelper')
}
Run Code Online (Sandbox Code Playgroud)

然后我require在任何测试中帮助我需要使用它:

// test/spec/MySpec.js
var helper = require('../test_helper');

// Or if you need just "MyHelper"
var myHelper = require('../test_helper').MyHelper;

describe('MySpec', function () {
   // Tests here...
});
Run Code Online (Sandbox Code Playgroud)

我更喜欢上述方法,因为它易于理解和灵活.您可以在我的演示中看到它的实际操作:https://github.com/paulredmond/karma-browserify-demo/tree/master/test


dai*_*a99 9

迟到的答案:-

Mocha(撰写时为 v7.0.0)支持指定file为选项:-
根据文档

  --file               Specify file(s) to be loaded prior to root suite
                       execution 
Run Code Online (Sandbox Code Playgroud)

.mocharc.json


{
    "watch-files": [
       "test/**/*.js"
    ],
    "recursive": true,
    "file": "test/setup"
}
Run Code Online (Sandbox Code Playgroud)

./test/setup.js

  --file               Specify file(s) to be loaded prior to root suite
                       execution 
Run Code Online (Sandbox Code Playgroud)

值得一提:

我发现上面的设置.js无论如何都加载了所有文件,可能是因为默认extension设置为mocha 配置js。由于我有用 命名所有测试文件的约定.spec.js,我可以通过添加忽略其他文件"ignore": ["test/**/!(*.spec.js)"]