`before()` 和 `beforeEach()` 有啥区别?

Posted

技术标签:

【中文标题】`before()` 和 `beforeEach()` 有啥区别?【英文标题】:What is the difference between `before()` and `beforeEach()`?`before()` 和 `beforeEach()` 有什么区别? 【发布时间】:2014-02-20 12:26:06 【问题描述】:

Mocha 的before()beforeEach() 之间具体有什么区别? (after()afterEach() 的问题相同。)

我假设before() 每个describe() 块运行一次,beforeEach() 每个测试运行一次(it() 块)。这是真的吗?

我什么时候会选择使用一个而不是另一个?

【问题讨论】:

【参考方案1】:

before()describe 中的所有测试之前运行一次after()describe 中的所有测试之后运行一次所有 beforeEach()describe 中的每个 测试之前运行afterEach()describe 中的每个 测试之后运行

您要使用哪一种取决于您的实际测试。

现在,进行冗长的解释。如果您在此运行mocha -R min

describe("top", function () 
    before(function () 
        console.log("top before");
    );
    after(function () 
        console.log("top after");
    );
    beforeEach(function () 
        console.log("top beforeEach");
    );
    afterEach(function () 
        console.log("top afterEach");
    );
    it("test1", function () 
        console.log("top test1");
    );
    describe("sublevel", function() 
        before(function () 
            console.log("sublevel before");
        );
        after(function () 
            console.log("sublevel after");
        );
        beforeEach(function () 
            console.log("sublevel beforeEach");
        );
        afterEach(function () 
            console.log("sublevel afterEach");
        );
        it("test1", function () 
            console.log("sublevel test1");
        );
        it("test2", function () 
            console.log("sublevel test2");
        );
    );
    it("test2", function () 
        console.log("top test2");
    );
);

你会看到类似的东西(我省略了不相关的输出):

top before
top beforeEach
top test1
top afterEach
top beforeEach
top test2
top afterEach
sublevel before
top beforeEach
sublevel beforeEach
sublevel test1
sublevel afterEach
top afterEach
top beforeEach
sublevel beforeEach
sublevel test2
sublevel afterEach
top afterEach
sublevel after
top after

如果您查看子级别的每个测试之前和之后执行的内容,可能会感到惊讶的是,both ***和子级别的 beforeEach 回调都被调用. afterEach 也是如此。

有些人还对sublevel beforetop beforeEachsublevel beforeEach 的顺序感到惊讶。他们认为外部作用域中的所有钩子都应该在内部作用域中的所有钩子之前执行,因此他们期望顺序为:top beforeEachsublevel beforesublevel beforeEach。但是,Mocha 执行钩子的顺序是完全有意义的:before 钩子旨在为一组测试奠定基础,而beforeEach 测试用于每个单独的测试。当 Mocha 执行测试时,在包含它的 describe 中设置的所有 beforebeforeEach 钩子,以及该 describe 的所有祖先都适用于测试。 Mocha 将从最外层作用域到最内层执行每个before 钩子,从最外层作用域到最内层执行所有beforeEach 钩子。 然而,所有应用的before 钩子都在任何beforeEach 钩子之前执行。这解释了上面的顺序:sublevel beforetop beforeEach 之前执行,因为它是一个before 钩子。对于afterafterEach,同样的逻辑适用,但顺序相反:所有适用的afterEach 钩子都在任何after 钩子之前执行。

另外请注意,相对于*** describe 中的 describe 调用,Mocha 并不关心我如何订购我的 it 调用。它执行top test1top test2然后子级别测试,即使我给出的顺序是top test1,然后是子级别测试,然后是top test2

您想在beforebeforeEach 等中使用什么实际上取决于您的测试的具体情况。如果您需要设置一个模拟对象或数据结构,并且该对象或结构可以在单个describe 中被所有测试重用,您可以使用before 进行设置,然后@ 987654368@ 将其拆除。如果您对结构进行只读测试,可能就是这种情况。如果您所有的测试都只读取它,那么就没有必要一遍又一遍地创建它。如果describe 中的每个测试都需要一个结构的 副本,因为每个测试都在修改结构,那么您应该使用beforeEach 为每个结构重新创建结构测试,然后 afterEach 如果你需要干净地拆掉它。这样做可以确保测试隔离:每个测试都从已知状态开始,并且不依赖于先前测试的存在与否来成功。

【讨论】:

太好了,谢谢。我的问题是部分是什么,部分是为什么,这两者都有,尤其是读/写之间的区别。 注意这些beforeAll等只在it-tests之前运行。如果您尝试直接在describe 中添加expect,这将发生在beforeAll 之前并导致令人困惑的错误。

以上是关于`before()` 和 `beforeEach()` 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

@Before、@BeforeClass、@BeforeEach 和 @BeforeAll 之间的区别

Protractor 中有 before() 函数吗?

Vue钩子函数

有关使用junit依赖出现@Before或者@Before注解不生效

为啥在 Quick 的单元测试中多次调用 before- 和 afterEach 块?

Laravel 5.1 + Vue.js - vue-router beforeEach AuthService