В чем разница между `before ()` и `beforeEach ()`?

90

В чем конкретно разница между Mocha 's before()и beforeEach()? (Тот же вопрос для after()и afterEach().)

Я предполагаю, что before()выполняется один раз на describe()блок и beforeEach()один раз на тест ( it()блок). Это правда?

И когда я выберу одно вместо другого?

Ericoco
источник

Ответы:

189

before()выполняется один раз перед тем, как все тесты в a describe
after()   запускаются один раз после того, как все тесты в a describe
beforeEach()выполняются перед запуском каждого теста в a 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

Дело в том, что может быть удивительно , если посмотреть на то , что выполняется до и после каждого из испытаний на подуровне является то , что оба эти beforeEachобратные вызовы на уровне верхней и на подуровне называются. То же самое и с afterEach.

Некоторые из них также удивлены последовательностью sublevel before, top beforeEach, sublevel beforeEach. Они думают , что все крючки в внешней области должны выполняться перед всеми крючками во внутреннем объеме, поэтому они ожидают , что последовательность: top beforeEach, sublevel before, sublevel beforeEach. Однако порядок, в котором Mocha выполняет хуки, вполне логичен: beforeловушка предназначена для подготовки группы тестов, тогда как beforeEachтест - для каждого отдельного теста. Когда Мокко выполняют тест, все beforeи beforeEachкрючки , которые были установлены в describeтом , что его содержит, и все предки , которые describeприменяются к испытанию. Mocha выполнит каждый beforeхук от самой внешней области видимости до самой внутренней и весь beforeEachхук от самой внешней области до самой внутренней. Однако, все beforeприменяемые хуки выполняются перед любым beforeEachхуком. Это объясняет приведенный выше порядок: sublevel beforeвыполняется раньше, top beforeEachпотому что это beforeперехватчик. А с afterи afterEachприменяется та же логика, но порядок обратный: все afterEachприменяемые хуки выполняются перед любым afterхуком.

Также обратите внимание, что Mocha не заботится о том, как я упорядочил свои itзвонки относительно describeзвонка на верхнем уровне describe. Он выполняет top test1, top test2а затем подуровневые тесты, хотя я дал такой порядок top test1, затем подуровневые тесты, а затем top test2.

То , что вы хотите использовать среди before, beforeEachи т.д. действительно зависит от специфики ваших тестов. Если вам нужно настроить фиктивный объект или структуру данных, и этот объект или структура могут быть повторно использованы всеми тестами в одном describe, вы можете использовать его beforeдля настройки и afterснятия. Это может иметь место, если вы выполняете тесты структуры только для чтения. Если все ваши тесты только читают его, то нет необходимости создавать его снова и снова. Если для каждого вашего теста describeтребуется новая копия структуры, потому что каждый тест изменяет структуру, вы должны использовать beforeEachдля создания структуры заново для каждого теста, а затемafterEachесли вам нужно его аккуратно снести. Это обеспечивает изоляцию теста: каждый тест начинается с известного состояния и не зависит от наличия или отсутствия предыдущего теста для успешного выполнения.

Луи
источник
1
Отлично, спасибо. Мой вопрос заключался в том, что частично и почему, это касается и того, и другого, особенно различия между чтением и записью.
ericsoco