简体   繁体   English

摩卡如何执行“ it”调用? 如何同步执行测试?

[英]How does Mocha execute the 'it' calls? How to execute tests synchronously?

Observe the following tests: 观察以下测试:

describe("Testing i", function(){

    var i = 0;
    it('i should be 0', function() {
        expect(i).to.equal(0);
    });

    i++;
    it('i should be 1', function() {
        expect(i).to.equal(1);
    });

    i= 7;
    it('i should be 7', function() {
        expect(i).to.equal(7);
    });
});

The first two tests fail. 前两个测试失败。 But I have no idea why! 但是我不知道为什么! What am I doing wrong? 我究竟做错了什么?

The test shows the following: 测试显示以下内容:

使用Mocha的NPM测试结果

I'm porting QUnit to Mocha and I'm looking where the asserts should go. 我正在将QUnit移植到Mocha,并且正在寻找断言应该放在哪里。
In QUnit you have Module -> Test -> Asserts. 在QUnit中,您具有模块->测试->断言。
Is it here Describe -> Describe -> It's? 是这里描述->描述->是吗?

You're doing the tests wrong. 您做错了测试。 The entire test, variable setup and all, MUST BE INSIDE the it functions. 整个测试,变量设置以及所有功能都必须包含在it功能范围之内。

What the it functions do is just push your tests to a list that will be executed either by the describe function or by mocha itself. it功能是将您的测试推送到将由describe函数或mocha本身执行的列表。 The it functions do NOT execute the tests. it功能不执行测试。

The correct way to write your test is as follows: 编写测试的正确方法如下:

describe("Testing i", function(){

    it('i should be 0', function() {
        var i = 0;
        expect(i).to.equal(0);
    });

    it('i should be 1', function() {
        var i = 0;
        i++;
        expect(i).to.equal(1);
    });

    it('i should be 7', function() {
        var i = 0;
        i = 7;
        expect(i).to.equal(7);
    });
});

FWIW. FWIW。 All tests are executed synchronously unless you pass an argument into the callback of the it function. 除非您将参数传递给it函数的回调,否则所有测试将同步执行。 It's just that they're not executed inside the describe function. 只是它们没有在describe函数中执行。 The it functions just compiles all your it calls into a list of tests. it的功能只是编译所有it调用到的测试列表。

Therefore, if you need to do a series of operations you can do this: 因此,如果您需要执行一系列操作,则可以执行以下操作:

describe("Testing i", function(){
    var i;

    it('i should be 0', function() {
        i = 0;
        expect(i).to.equal(0);
    });

    it('i should be 1', function() {
        i++;
        expect(i).to.equal(1);
    });

    it('i should be 7', function() {
        i = 7;
        expect(i).to.equal(7);
    });
});

Note however that this is not recommended because if the first test fails then some of the following tests may fail as well. 但是请注意,不建议这样做,因为如果第一个测试失败,则随后的某些测试也可能会失败。 In this example, if the first test fails because the value of i is not 0 the second test will fail too. 在此示例中,如果第一个测试由于i的值不为0而失败,则第二个测试也将失败。 However, this pattern may be useful for steps that take a long time to execute (website login for example). 但是,此模式对于执行时间较长的步骤(例如,网站登录)可能很有用。


Why do it this way? 为什么要这样呢?

This allows mocha to do fancy test reporting like progress bars etc. Without knowing how many tests there are to run (a test is an it function), mocha cannot know what percentage to draw the progress bar. 这使mocha可以进行进度条等类似的花式测试报告。在不知道要运行多少个测试(一项测试是it功能)的情况下,mocha无法知道绘制进度条的百分比。

It also allows mocha to do fancy formatting of error messages. 它还允许摩卡(mocha)对错误消息进行精美的格式化。 If you've used mocha, you'll notice that mocha collects all error messages (fails) and print them at the end. 如果您使用过mocha,则会注意到mocha会收集所有错误消息(失败)并在最后打印它们。 To do that what mocha does is execute the tests ( it functions) one at a time in a controlled manner and collecting any errors thrown. 为此,mocha要做的是一次以受控方式执行一次测试( it起作用),并收集抛出的所有错误。 That's not possible if you rely on javascript syntax alone unless you hack the interpreter in C. But you can do that if you have a list of functions inside an array and execute them one function at a time. 如果您仅依靠JavaScript语法,除非您用C语言破解了解释器,否则这是不可能的。但是,如果您在数组中有一系列函数并一次执行一个函数,则可以这样做。

Answering to question, how the execution flow works. 回答问题,执行流程如何工作。 Mocha starts with describe block. 摩卡咖啡从描述块开始。

In describe block first of all it executes all the code that is not in the it block. 首先在describe块中,它执行不在it块中的所有代码。

So in your code first of all these 3 statements are executed before executing it blocks 因此,在你的代码首先这3条语句执行之前执行it的块

var i = 0;
  i++;
  i=7;

Last value assigned to i is 7. Now it will start executing it blocks. 分配给i的最后一个值是7。现在它将开始执行它的块。

A Solution like on the Mocha Documentation https://mochajs.org/ 类似于Mocha文档 https://mochajs.org/ 上的解决方案

describe("Testing i", function(){

    var i;
    it('i should be 0', function() {
        i = 0;
        expect(i).to.equal(0);
    });


    it('i should be 1', function() {
        i++;
        expect(i).to.equal(1);
    });

    it('i should be 7', function() {
        i= 7;
        expect(i).to.equal(7);
    });
});

The calling order, as asked in the Question 问题中要求的呼叫顺序
I tested it with a adapted code from this article http://cwinters.com/2014/09/26/mocha-nested-hook-ordering.html 我使用本文http://cwinters.com/2014/09/26/mocha-nested-hook-ordering.html中的改编代码对其进行了测试

Here is the code, I used 这是我使用的代码

'use strict';

describe('level 1', function() {
  before(function() { console.log("L1 - before") });
  beforeEach(function() { console.log("L1 - beforeEach") });
  after(function() { console.log("L1 - after") });
  afterEach(function() { console.log("L1 - afterEach") });

console.log("inner DESCRIBE BEFORE L1A")  // equivalent to asigning the variable the first time
  it('L1 test A', function() {});
 console.log("inner DESCRIBE BEFORE L1B") // equivalent to asigning the variable the second time
  it('L1 test B', function() {});

  describe('level 2', function() {
    before(function() { console.log("L2 - before") });
    beforeEach(function() { console.log("L2 - beforeEach") });
    after(function() { console.log("L2 - after") });
    afterEach(function() { console.log("L2 - afterEach") });

    it('L2 test A', function() {});
    it('L2 test B', function() {});
  });
});

here the result 结果在这里

inner DESCRIBE BEFORE L1A     // execute First
inner DESCRIBE BEFORE L1B     // execute Second


  level 1                     // now the test are executed
L1 - before
L1 - beforeEach
    √ L1 test A
L1 - afterEach
L1 - beforeEach
    √ L1 test B
L1 - afterEach
    level 2
L2 - before
L1 - beforeEach
L2 - beforeEach
      √ L2 test A
L2 - afterEach
L1 - afterEach
L1 - beforeEach
L2 - beforeEach
      √ L2 test B
L2 - afterEach
L1 - afterEach
L2 - after
L1 - after


4 passing (64ms)

=> The describe Block will be execute immediately, so multiple variable asignment to the same varible will be overriden by the last one, before any other function is called. => describe块将立即执行,因此在调用任何其他函数之前,最后一个变量将覆盖对同一变量的多个变量赋值。 The first two test Fail because i==7 when all three tests are executed. 前两个测试失败,因为在执行所有三个测试时i==7

If the sequence is really needed you could use closure , but this would add a lot more complexity . 如果确实需要该序列,则可以使用闭包,但这会增加很多复杂性

Looks like the following is the way to go: 看起来下面是要走的路:

describe("Testing i", function(){

    it('i increments', function(){

        var i = 0;
        expect(i, 'i should be 0').to.equal(0);

        i++;
        expect(i, 'i should be 1').to.equal(1);

        i = 7;
        expect(i, 'i should be 7').to.equal(7);
    });

});

The QUnit.module maps to describe , QUnit.test maps to it and assert maps to expect . QUnit.module映射来describeQUnit.test映射到it并且assert映射以expect

I've written a blog on the subject: Convert QUnit test to Mocha / Chai . 我已经写了一个关于以下主题的博客: 将QUnit测试转换为Mocha / Chai

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

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