简体   繁体   English

摩卡的全局“before”和“beforeEach”?

[英]Global `before` and `beforeEach` for mocha?

I'm using mocha for javascript unit-testing now.我现在正在使用 mocha 进行 javascript 单元测试。

I have several test files, each file has a before and beforeEach , but they are exactly the same.我有几个测试文件,每个文件都有一个beforebeforeEach ,但它们完全一样。

How do I provide a global before and beforeEach for all of them (or some of them)?我如何为所有这些(或其中一些)提供一个全局beforebeforeEach

In the root of the test folder, create a global test helper test/helper.js which has your before and beforeEach在 test 文件夹的根目录中,创建一个全局测试助手test/helper.js ,其中包含您的 before 和 beforeEach

// globals
global.assert = require('assert');

// setup
before();
beforeEach();

// teardown
after();
afterEach();

from the mocha documentation来自摩卡文档……

ROOT-LEVEL HOOKS根级挂钩

You may also pick any file and add “root”-level hooks.您还可以选择任何文件并添加“根”级挂钩。 For example, add beforeEach() outside of all describe() blocks.例如,在所有 describe() 块之外添加 beforeEach()。 This will cause the callback to beforeEach() to run before any test case, regardless of the file it lives in (this is because Mocha has an implied describe() block, called the “root suite这将导致对 beforeEach() 的回调在任何测试用例之前运行,无论它位于哪个文件中(这是因为 Mocha 有一个隐含的 describe() 块,称为“根套件”

All regular describe() -suites are first collected and only then run, this kinda guarantees this being called first.首先收集所有常规的describe() -suites,然后才运行,这有点保证首先调用它。

'use strict'
let run = false

beforeEach(function() {
    if ( run === true ) return
    console.log('GLOBAL ############################')
    run = true
});

Remove the run-flag, if you want to see it run each time, before every test.如果您想在每次测试之前每次都看到它运行,请删除运行标志。

I named this file test/_beforeAll.test.js .我将此文件命名为test/_beforeAll.test.js It has no need to be imported/required anywhere, but the .test.它不需要在任何地方导入/需要,但.test. (resp. .spec. ) in the filename is important, so that your testrunner picks it up…文件名中的 (resp. .spec. ) 很重要,这样您的测试运行程序就会发现它……


bonus track 8-): using mocha.opts \\o/奖励曲目 8-):使用mocha.opts \\o/

If there's stuff, you truly only want to set up once before running your tests (regardless which ones...), mocha.opts is a surprisingly elegant option!如果有东西,你真的只想在运行你的测试之前设置一次(不管是什么......), mocha.opts是一个非常优雅的选择! – Just add a require to your file (yes, even if it contributes little to mocha, but rather to your test setup). – 只需在您的文件中添加一个require (是的,即使它对 mocha 的贡献很小,但对您的测试设置却有贡献)。 It will run reliably once before:它之前会可靠地运行一次:

在此处输入图片说明

( in this example I detect, if a single test or many tests are about to run. In the former case I output every log.info() , while on a full run I reduce verbosity to error+warn... ) (在这个例子中,我检测,如果单个测试或多个测试即将运行。在前一种情况下,我输出每个log.info() ,而在完整运行时,我将详细程度减少到错误+警告......)

Update:更新:

If someone knows a way, to access some basic properties of the mocha suite that is about to be run in once.js , I would love to know and add here.如果有人知道一种方法来访问即将在once.js运行的 mocha 套件的一些基本属性,我很想知道并在此处添加。 (ie my suiteMode -detection is lousy, if there was another way to detect, how many tests are to be run…) (即我的suiteMode很糟糕,如果有另一种检测方式,要运行多少测试......)

Declare a before or beforeEach in a separate file (I use spec_helper.coffee ) and require it.在单独的文件中声明beforebeforeEach (我使用spec_helper.coffee )并要求它。

spec_helper.coffee spec_helper.coffee

afterEach (done) ->
  async.parallel [
    (cb) -> Listing.remove {}, cb
    (cb) -> Server.remove {}, cb
  ], ->
    done()

test_something.coffee test_something.coffee

require './spec_helper'

I've had similar issue when I needed to "mock" global variables used by one of dependencies.当我需要“模拟”依赖项之一使用的全局变量时,我遇到了类似的问题。

I used .mocharc.js for that, since code in that JS file is being executed once when "mocha" environment is being setup.我为此使用了 .mocharc.js,因为在设置“mocha”环境时,该 JS 文件中的代码将被执行一次。

Example .mocharc.js:示例 .mocharc.js:

global.usedVariable = "someDefinedValue";

/** other code to be executed when mocha env setup **/

module.exports = {};

This worked for me, nevertheless this looks quite "dirty" way to do that.这对我有用,但是这看起来很“肮脏”的方式来做到这一点。 Please, comment if you know a better place for that code :)如果您知道该代码的更好位置,请发表评论:)

mochaHooks root hook plugin minimal example on Mocha 8 mochaHooks根挂钩插件 Mocha 8 上的最小示例

This mechanism is currently documented at: https://mochajs.org/#root-hook-plugins该机制目前记录在: https : //mochajs.org/#root-hook-plugins

It does not work for before , only for beforeEach however, since before is not in the list of available hooks from: https://mochajs.org/#available-root-hooks它不适用于before ,仅适用于beforeEach但是,因为before不在可用钩子列表中: https : beforeEach

Here's a demo:这是一个演示:

test/global.js测试/global.js

// Root hook.
exports.mochaHooks = {
  beforeEach(done) {
    console.log('mochaHooks.beforeEach');
    done();
  },
};

// Bonus: global fixture, runs once before everything.
exports.mochaGlobalSetup = async function() {
  console.log('mochaGlobalSetup');
};

test/mytest.js测试/mytest.js

var assert = require('assert');

describe('describe0', function() {
  // Only runs before the current describe.
  before(async () => {
    console.error('before describe 0');
  });
  beforeEach(async () => {
    console.error('beforeEach describe 0');
  });
  it('it 0 0', function() {
    assert.equal(0, 0);
  });
  it('it 0 1', function() {
    assert.equal(0, 0);
  });

  describe('describe 0 0', function() {
    before(async () => {
      console.error('before describe 0 0');
    });
    beforeEach(async () => {
      console.error('beforeEach describe 0 0');
    });
    it('it 0 0 0', function() {
      assert.equal(0, 0);
    });
    it('it 0 0 1', function() {
      assert.equal(0, 0);
    });
  });

  describe('describe 0 1', function() {
    before(async () => {
      console.error('before describe 0 1');
    });
    beforeEach(async () => {
      console.error('beforeEach describe 0 1');
    });
    it('it 0 1 0', function() {
      assert.equal(0, 0);
    });
    it('it 0 1 1', function() {
      assert.equal(0, 0);
    });
  });
});

Then you enable that file with --require :然后使用--require启用该文件:

npx mocha --require test/global.js test/

Outcome:结果:

mochaGlobalSetup


  describe0
before describe 0
mochaHooks.beforeEach
beforeEach describe 0
    ✓ it 0 0
mochaHooks.beforeEach
beforeEach describe 0
    ✓ it 0 1
    describe 0 0
before describe 0 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 0
      ✓ it 0 0 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 0
      ✓ it 0 0 1
    describe 0 1
before describe 0 1
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 1
      ✓ it 0 1 0
mochaHooks.beforeEach
beforeEach describe 0
beforeEach describe 0 1
      ✓ it 0 1 1


  6 passing (6ms)

So we see that the global hook ran before every local beforeEach .所以我们看到全局钩子在每个本地beforeEach之前beforeEach

For before I couldn't find a better solution than defining a helper and calling it from every before : How can I make Mocha load a helper.js file that defines global hooks or utilities?因为before我找不到比定义一个助手并从每个before调用它更好的解决方案: 如何让 Mocha 加载一个定义全局钩子或实用程序的 helper.js 文件?

Tested on mocha 8.3.2, Node v14.16.0.在 mocha 8.3.2、Node v14.16.0 上测试。

The use of a modules can make it easier to have a global setup/teardown for your test suite.使用模块可以更轻松地为您的测试套件进行全局设置/拆卸。 Here is an example using RequireJS (AMD modules):下面是一个使用 RequireJS(AMD 模块)的例子:

First, let's define a test environment with our global setup/teardown:首先,让我们使用全局设置/拆卸定义一个测试环境:

// test-env.js

define('test-env', [], function() {
  // One can store globals, which will be available within the
  // whole test suite.
  var my_global = true;

  before(function() {
    // global setup
  });
  return after(function() {
    // global teardown
  });
});

In our JS runner (included in mocha's HTML runner, along the other libs and test files, as a <script type="text/javascript">…</script> , or better, as an external JS file):在我们的 JS 运行器中(包含在 mocha 的 HTML 运行器中,连同其他库和测试文件,作为<script type="text/javascript">…</script> ,或者更好,作为外部 JS 文件):

require([
          // this is the important thing: require the test-env dependency first
          'test-env',

          // then, require the specs
          'some-test-file'
        ], function() {

  mocha.run();
});

some-test-file.js could be implemented like this: some-test-file.js可以这样实现:

// some-test-file.js

define(['unit-under-test'], function(UnitUnderTest) {
  return describe('Some unit under test', function() {
    before(function() {
      // locally "global" setup
    });

    beforeEach(function() {
    });

    afterEach(function() {
    });

    after(function() {
      // locally "global" teardown
    });

    it('exists', function() {
      // let's specify the unit under test
    });
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM