【问题标题】:Make Mocha wait before running next test在运行下一个测试之前让 Mocha 等待
【发布时间】:2014-10-21 16:00:29
【问题描述】:

我有一些 mocha 测试需要来自先前函数调用的数据。但是,由于我的代码使用的是 Web 服务,因此我希望它在运行下一个测试之前等待一段预定的时间。

类似这样的:

var global;

it('should give some info', function(done) {
  run.someMethod(param, function(err, result) {
    global = result.global
  done();
  });
});

wait(30000); // basically block it from running the next assertion

it('should give more info', function(done) {
  run.anotherMethod(global, function(err, result) {
    expect(result).to.be.an('object');
  done();
  });
});

任何想法将不胜感激。谢谢!

【问题讨论】:

    标签: javascript node.js mocha.js


    【解决方案1】:

    在我的例子中,我在NodeJS 中编写了一个RESTful API,它在本地操作一些文件。当我启动测试时,API 接收到多个请求,这使我的 API 同时操作机器中的这些文件,这导致我遇到了一个问题。

    所以,我需要在这些 API 调用之间留出一些时间(1 sec 就足够了)。对我来说,解决方案如下:

    beforeEach( async () => {
       await new Promise(resolve => setTimeout(resolve, 1000));
       console.log("----------------------");
    });
    

    现在,在每个 it() 测试之前,前一个函数运行,API 调用之间我有 1 秒的睡眠时间。

    【讨论】:

    • 完美!这应该是 IMO 接受的答案。
    【解决方案2】:

    setTimeout 肯定会有所帮助,但可能有一种“更清洁”的方式来做到这一点。

    The documentation here 实际上是说使用this.timeout(delay) 来避免在测试异步代码时出现超时错误,所以要小心。

    var global;
    
    it('should give some info', function(done) {
      run.someMethod(param, function(err, result) {
        global = result.global
      done();
      });
    });
    
    it('should give more info', function(done) {
        this.timeout(30000);
    
        setTimeout(function () {
          run.anotherMethod(global, function(err, result) {
            expect(result).to.be.an('object');
            done();
          });
        }, 30000);
     });
    

    【讨论】:

    • 谢谢,Flops,现在可以了。我在测试时写错了我现在意识到的 setTimeout。谢谢:)
    • 我以为问题是关于两个连续测试保持顺序?
    • Zlatko,问题是关于查询中下一个测试的延迟执行。这个例子中的 this.settimeout 是为了避免超时错误,如果我是对的,mocha 中的默认值为 20000。
    • “得到了一些 mocha 测试,需要来自先前函数调用的数据”来自 OP 的问题告诉我,他只需要等待上一个测试完成,而不是让当前测试超时。我不知何故错过了“愿意等待”部分。另外,感谢您的评论,但如果它是在被否决的问题上,对我来说会更明显。
    • 我喜欢第一个示例中的清洁度。帮了我很多,谢谢
    【解决方案3】:

    第一:

    这个帖子有很好的答案!我个人很喜欢@Flops 的回答(得到了我的支持)

    第二:

    为了澄清这一点(尽可能),这里有一个与我最终得到的代码示例非常相似(经过测试和验证)

    function delay(interval) 
    {
       return it('should delay', done => 
       {
          setTimeout(() => done(), interval)
    
       }).timeout(interval + 100) // The extra 100ms should guarantee the test will not fail due to exceeded timeout
    }
    
    it('should give some info', function(done) {
      run.someMethod(param, function(err, result) {
        global = result.global
      done();
      });
    });
    
    delay(1000)
    
    it('should give more info', function(done) {
      run.anotherMethod(global, function(err, result) {
        expect(result).to.be.an('object');
      done();
      });
    });
    

    旁注:您也可以一个接一个地使用延迟函数,并且仍然保持一致性(测试顺序)

    【讨论】:

      【解决方案4】:

      这是另一个,使用承诺:

      it('go, then stop', (done) => {
      // this.skip();
      go()
        .then((response) => { console.log('go was called'); return response; })
        .then(response => response.should.equal('acknowledged'))
        .then(() => new Promise(resolve => setTimeout(() => { resolve(); }, 3000)))
        .then(() => console.log('3 second wait is over'))
        .then(() => stop())
        .then(response => response.should.equal('acknowledged'))
        .then(() => done());
        }).timeout(15000);
      

      【讨论】:

        【解决方案5】:

        首先,对于正确的单元测试,您永远不需要在测试之间进行一些睡眠。如果您确实需要睡眠,这意味着您正在测试的函数在完成其预期任务之前需要延迟,该任务必须在该函数内部处理,并带有一些异步等待或睡眠。从函数退出后,它的生命周期必须结束,并且必须立即获得预期的结果。

        【讨论】:

        • 我同意。如果您有一个需要长时间延迟的单元测试,那么它可能不是真正的单元测试!单元测试应该只测试逻辑和功能之间的有限集成。你应该考虑嘲笑任何需要时间的东西。
        • “你不应该在测试之间睡觉”。你永远不应该说永远。我需要在测试之间睡觉,因为我使用的 Web 服务每分钟的 API 调用次数是有限的。如果我只是在不睡觉的情况下运行测试,那么多个测试将失败。在 it() 函数中设置睡眠是可行的,但会增加 12000 毫秒的函数执行时间,这是完全错误的。
        • @ThomasW 然后,您应该在调用 API 函数之前,在测试函数中添加 sleep 调用。不在测试函数之间。
        • 如前所述,这意味着我得到了测试时间的偏差指示。然后我所有的测试时间变成红色到 +12000 毫秒。我宁愿在两者之间等待,这样测试时间就不会包含这种偏见。如果有办法从测试结果中删除它,那么是的,我同意你的看法。
        • @ThomasW 你假设测试函数调用的特定顺序吗?理想情况下,您不应该这样做。如果没有假定顺序,则调用之间没有常数“之间”。
        【解决方案6】:

        虽然this.timeout() 会延长单次测试的超时时间,但这不是您问题的答案。 this.timeout() 设置当前测试的超时时间。

        不过别担心,反正你应该没事的。测试不是并行运行的,而是串行进行的,因此您的全局方法应该没有问题。

        【讨论】:

        • 实际上,它们是并行运行的,不是吗?还是并行与异步不同? mochajs.org
        • 你是对的,并行!==异步。特别是摩卡测试,它们是串联运行的。一个,比另一个,比下一个等等。
        猜你喜欢
        • 2019-11-03
        • 1970-01-01
        • 2019-04-25
        • 1970-01-01
        • 2020-06-22
        • 2021-01-23
        • 2018-11-17
        • 2019-06-07
        • 1970-01-01
        相关资源
        最近更新 更多