Jaka jest różnica między `before ()` i `beforeEach ()`?

90

Co konkretnie jest różnica między Mocha „s before()a beforeEach()? (To samo pytanie dla after()i afterEach().)

Zakładam, że before()działa raz na describe()blok i beforeEach()działa raz na test ( it()blok). Czy to prawda?

A kiedy zdecydowałbym się użyć jednego nad drugim?

ericsoco
źródło

Odpowiedzi:

188

before()jest uruchamiany jeden raz przed wykonaniem wszystkich testów w a, describe
after()   jeden raz po wykonaniu wszystkich testów w a, describe
beforeEach()przed każdym testem w a, describe
afterEach()   po każdym teście w adescribe

Który z nich chcesz użyć, zależy od twojego rzeczywistego testu.

Teraz długie wyjaśnienie. Jeśli uruchomisz mocha -R minna tym:

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

Zobaczysz coś takiego (pominąłem dane wyjściowe, które nie są istotne):

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

Tym, co może być zaskakujące, jeśli spojrzeć na to, co wykonuje przed i po każdym z testów w podpoziomu jest to, że oba te beforeEachwywołania zwrotne na poziomie górnym i na podpoziomu są nazywane. To samo dotyczy afterEach.

Niektóre z nich są również zaskoczony przez sekwencję sublevel before, top beforeEach, sublevel beforeEach. Myślą, że wszystkie haki w zakresie zewnętrznej należy wykonać przed wszystkimi hakami w zakresie wewnętrznym, więc spodziewać się sekwencję: top beforeEach, sublevel before, sublevel beforeEach. Jednak kolejność, w jakiej Mocha wykonuje haczyki, ma sens: beforehak służy do ustawiania sceny dla grupy testów, podczas gdy beforeEachtest jest przeznaczony dla każdego pojedynczego testu. Kiedy Mocha wykonuje test, wszystkobefore i beforeEachhaczyki, które zostały określone w describektóry go zawiera, i wszyscy przodkowie, które describestosuje się do testu. Mocha wykona każdy beforehak od najbardziej zewnętrznego zakresu do najbardziej wewnętrznego i wszystkie beforeEachhaki od najbardziej zewnętrznego zakresu do najbardziej wewnętrznego. jednak, wszystkie beforezastosowane zaczepy są wykonywane przed jakimkolwiek beforeEachzaczepem. To wyjaśnia powyższą kolejność: sublevel beforewykonuje się przed, top beforeEachponieważ jest to beforehak. W przypadku afteri afterEachobowiązuje ta sama logika, ale kolejność jest odwrotna: wszystkie afterEachzastosowane zaczepy są wykonywane przed jakimkolwiek afterzaczepem.

Zauważ również, że Mocha nie dba o to, jak uporządkowałem moje itpołączenia w stosunku do describepołączenia na najwyższym poziomie describe. Wykonuje top test1, top test2a następnie testy podpoziomowe, mimo że podałem kolejność top test1, potem testy podpoziomu i wtedy top test2.

Co chcesz użyć wśród before, beforeEachitp naprawdę zależy od specyfiki firmy testów. Jeśli potrzebujesz skonfigurować pozorowany obiekt lub strukturę danych, a ten obiekt lub struktura może być ponownie wykorzystana we wszystkich testach w jednym describe, możesz użyć go beforedo skonfigurowania i afterzniszczenia. Może tak być w przypadku wykonywania testów tylko do odczytu struktury. Jeśli wszystkie twoje testy tylko go odczytują, nie ma potrzeby tworzenia go wielokrotnie. Jeśli każdy test describewymaga nowej kopii struktury, ponieważ każdy test modyfikuje strukturę, powinieneś użyć beforeEachdo utworzenia struktury od nowa dla każdego testu, a następnieafterEachjeśli chcesz go dokładnie rozebrać. Takie postępowanie zapewnia izolację testu: każdy test zaczyna się od znanego stanu i nie jest zależny od obecności lub braku poprzedniego testu, aby zakończyć się pomyślnie.

Louis
źródło
1
Wielkie dzięki. Moje pytanie dotyczyło po części „co” i po części „dlaczego”, to gwoździ jedno i drugie, zwłaszcza różnicę między czytaniem i pisaniem.
ericsoco