【问题标题】:Global `before` and `beforeEach` for mocha?摩卡的全局`before`和`beforeEach`?
【发布时间】:2012-05-20 15:42:38
【问题描述】:

我现在正在使用 mocha 进行 javascript 单元测试。

我有几个测试文件,每个文件都有beforebeforeEach,但是它们完全一样。

我如何为所有(或其中一些)提供全局 beforebeforeEach

【问题讨论】:

    标签: javascript unit-testing mocha.js


    【解决方案1】:

    在 test 文件夹的根目录下,创建一个全局测试助手test/helper.js,其中包含你的 before 和 beforeEach

    // globals
    global.assert = require('assert');
    
    // setup
    before();
    beforeEach();
    
    // teardown
    after();
    afterEach();
    

    【讨论】:

    • 您不必明确要求它。事实上,它会抛出一个错误,因为 before、beforeEach 等将不存在于所需的上下文中。只要它包含在测试目录中,代码就应该在任何测试之前执行。
    • 感谢@khoomeister 的旧版本!更新
    • 我用这个,很好,但不知道在哪里可以找到它的文档?
    • 它在 Mocha 网站上:“请注意,您还可以选择任何文件并添加“根”级挂钩,例如在 describe() 之外添加 beforeEach(),然后回调将在任何之前运行测试用例,不管它的文件是什么。这是因为 Mocha 有一个没有名称的根套件。”。看this section, bottom part
    • 直接链接到@kamituel 正在谈论的内容:mochajs.org/#root-level-hooks
    【解决方案2】:

    来自mocha documentation

    根级挂钩

    您还可以选择任何文件并添加“根”级挂钩。例如, 在所有 describe() 块之外添加 beforeEach()。这将导致 回调 beforeEach() 以在任何测试用例之前运行,无论 它所在的文件(这是因为 Mocha 有一个隐含的 describe() 块,称为“根套件”

    首先收集所有常规的describe()-suites,然后然后运行,这样可以保证首先调用它。

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

    如果您想在每次测试之前看到它每次运行,请删除运行标志。

    我将此文件命名为test/_beforeAll.test.js。它不需要在任何地方导入/需要,但文件名中的.test.(resp..spec.)很重要,这样你的测试运行者就会选择它……


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

    如果有东西,您真的只想在运行测试之前设置一次(不管是哪个...),mocha.opts 是一个令人惊讶的优雅选择! – 只需将require 添加到您的文件中(是​​的,即使它对 mocha 贡献很小,但对您的测试设置贡献不大)。之前会可靠运行一次:

    (在这个例子中,我检测到,如果一个测试或多个测试即将运行。在前一种情况下,我输出每个log.info(),而在完全运行时,我将详细程度降低到错误+警告...)

    更新:

    如果有人知道一种方法,可以访问即将在 once.js 中运行的 mocha 套件的一些基本属性,我很想知道并在这里添加。 (即我的suiteMode-detection 很糟糕,如果有其他方法可以检测,要运行多少测试......)

    【讨论】:

    • 现在可以在所需文件中直接访问之前/之后等(看起来 mocha 在调用所需文件之前已实例化)
    【解决方案3】:

    在单独的文件中声明beforebeforeEach(我使用spec_helper.coffee)并要求它。

    spec_helper.coffee

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

    test_something.coffee

    require './spec_helper'
    

    【讨论】:

    • 你能解释一下吗,那里发生了什么?
    【解决方案4】:

    mochaHooks Mocha 8 上的根挂钩插件最小示例

    此机制目前记录在:https://mochajs.org/#root-hook-plugins

    它不适用于before,但仅适用于beforeEach,因为before 不在来自https://mochajs.org/#available-root-hooks 的可用挂钩列表中

    这是一个演示:

    test/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

    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);
        });
      });
    });
    

    然后你用--require启用那个文件:

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

    结果:

    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)
    

    所以我们看到全局挂钩在每个本地 beforeEach 之前运行。

    对于before,我找不到比定义一个助手并从每个before 调用它更好的解决方案:How can I make Mocha load a helper.js file that defines global hooks or utilities?

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

    【讨论】:

      【解决方案5】:

      当我需要“模拟”一个依赖项使用的全局变量时,我遇到了类似的问题。

      我为此使用了 .mocharc.js,因为在设置“mocha”环境时,该 JS 文件中的代码会被执行一次。

      示例 .mocharc.js:

      global.usedVariable = "someDefinedValue";
      
      /** other code to be executed when mocha env setup **/
      
      module.exports = {};
      

      这对我有用,但是这样做看起来很“肮脏”。 如果您知道该代码的更好位置,请发表评论:)

      【讨论】:

        【解决方案6】:

        使用模块可以更轻松地为您的测试套件进行全局设置/拆卸。这是一个使用 RequireJS(AMD 模块)的示例:

        首先,让我们使用全局设置/拆卸来定义一个测试环境:

        // 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
          });
        });
        

        在我们的 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 可以这样实现:

        // 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
            });
          });
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-26
          • 2019-11-02
          • 1970-01-01
          • 2014-02-20
          • 2023-03-24
          • 1970-01-01
          • 2012-05-20
          • 1970-01-01
          相关资源
          最近更新 更多