Qual é a diferença entre `before ()` e `beforeEach ()`?

91

O que especificamente é a diferença entre Mocha 's before()e beforeEach()? (Mesma pergunta para after()e afterEach().)

Presumo que seja before()executado uma vez por describe()bloco e beforeEach()uma vez por teste ( it()bloco). Isso é verdade?

E quando eu escolheria usar um em vez do outro?

Ericsoco
fonte

Respostas:

191

before()é executado uma vez antes de todos os testes em a describe
after()   ser executado uma vez após todos os testes em a describe
beforeEach()serem executados antes de cada teste em a describe
afterEach()   ser executado após cada teste em umdescribe

Qual você deseja usar depende do seu teste real.

Agora, para a longa explicação. Se você correr mocha -R minneste:

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

Você verá algo como (Omiti a saída que não é relevante):

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

A única coisa que pode ser surpreendente se você olhar para o que é executado antes e depois de cada um dos testes no subnível é que ambos os beforeEachretornos de chamada no nível superior e no subnível são chamados. A mesma coisa para o afterEach.

Alguns também são surpreendidos pela sequência sublevel before, top beforeEach, sublevel beforeEach. Eles pensam que todos os ganchos em um escopo externo deve executar antes de todos os ganchos em um âmbito interno, por isso eles esperam que a sequência: top beforeEach, sublevel before, sublevel beforeEach. No entanto, a ordem em que o Mocha executa os ganchos faz todo o sentido: um beforegancho serve para preparar o cenário para um grupo de testes, enquanto um beforeEachteste é para cada teste individual. Quando o Mocha executa um teste, todos os beforee os beforeEachganchos que foram definidos no describeque o contém, e todos os ancestrais que se describeaplicam ao teste. O Mocha executará cada beforegancho do escopo externo para o interno, e todos os beforeEachganchos do escopo externo para o interno. Contudo, todos os beforeganchos que se aplicam são executados antes de qualquer beforeEachgancho. Isso explica a ordem acima: sublevel beforeexecuta antes top beforeEachporque é um beforegancho. E com aftere afterEach, a mesma lógica se aplica, mas a ordem é invertida: todos os afterEachganchos que se aplicam são executados antes de qualquer aftergancho.

Observe também que Mocha não se preocupa com a forma como ordenei minhas itchamadas em relação à describechamada no nível superior describe. Ele executa top test1, top test2e depois os testes de subnível, mesmo que a ordem que dei foi top test1, depois os testes de subnível e então top test2.

O que você deseja usar entre before, beforeEachetc. depende realmente das especificações de seus testes. Se você precisa configurar um objeto mock ou estrutura de dados e este objeto ou estrutura pode ser reutilizado por todos os testes em um único describe, você pode usar beforepara configurá-lo e afterderrubá-lo. Esse pode ser o caso se você estiver fazendo testes somente leitura na estrutura. Se todos os seus testes apenas lêem, não há necessidade de criá-lo continuamente. Se cada teste em sua describeprecisa de uma nova cópia da estrutura porque cada teste está modificando a estrutura, você deve usar beforeEachpara criar a estrutura novamente para cada teste e, em seguida,afterEachse você precisar derrubá-lo de forma limpa. Isso garante o isolamento do teste: cada teste começa em um estado conhecido e não depende da presença ou ausência de um teste anterior para ter sucesso.

Louis
fonte
1
Otimo obrigado. Minha pergunta era parte o quê e parte por quê, isso acerta ambos, especialmente a distinção entre ler / escrever.
ericsoco