Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between `before()` and `beforeEach()`?

What specifically is the difference between Mocha's before() and beforeEach()? (Same question for after() and afterEach().)

I assume before() runs once per describe() block, and beforeEach() runs once per test (it() block). Is that true?

And when would I choose to use one over the other?

like image 733
ericsoco Avatar asked Jan 28 '14 22:01

ericsoco


People also ask

What is before and beforeEach in Cypress?

before − It is executed, once the prior execution of any tests within a describe block is carried out. after − It is executed, once the post execution of all the tests within a describe block is carried out. beforeEach − It is executed prior to the execution of an individual, it blocks within a describe block.

What is beforeEach used for?

beforeAll and beforeEach , along with afterAll and afterEach , are Jasmine global functions that can be used manage expensive setup and teardown in test suites.

Does beforeAll run before beforeEach?

You can read this article https://jestjs.io/docs/en/setup-teardown.html on Jest document. Note, that a scoped beforeAll in a nested describe will run before a parent beforeEach . So if you depend on something in a parent beforeEach in your scoped beforeAll , it will not have run yet.

In what case would you need to use beforeEach () or afterEach () in a test suite?

The difference is beforeEach()/afterEach() automatically run before and after each tests, which 1. removes the explicit calls from the tests themselves, and 2. invites inexperienced users to share state between tests. Tests should be explicit, and tests should never share state.


1 Answers

before() is run once before all the tests in a describe
after()   is run once after all the tests in a describe
beforeEach() is run before each test in a describe
afterEach()   is run after each test in a describe

Which one you want to use depends on your actual test.

Now, for the long explanation. If you run mocha -R min on this:

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

You'll see something like (I've omitted the output that is not relevant):

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 

The thing that may be surprising if you look at what executes before and after each of the tests at the sublevel is that both the beforeEach callbacks at the top level and at the sublevel are called. Same thing for the afterEach.

Some are also surprised by the sequence sublevel before, top beforeEach, sublevel beforeEach. They think that all the hooks in an outer scope should execute before all the hooks in an inner scope, so they expect the sequence: top beforeEach, sublevel before, sublevel beforeEach. However, the order in which Mocha executes the hooks makes complete sense: a before hook is meant to set the stage for a group of tests, whereas a beforeEach test is for each individual tests. When Mocha executes a test, all the before and the beforeEach hooks that were set in the describe that contains it, and all the ancestors of that describe apply to the test. Mocha will execute each before hook from the outermost scope to the innermost, and all beforeEach hook from the outermost scope to the innermost. However, all before hooks that apply are executed before any beforeEach hook. This explains the order above: sublevel before executes before top beforeEach because it is a before hook. And with after and afterEach, the same logic applies but the the order is reversed: all afterEach hooks that apply are executed before any after hook.

Also notice that Mocha does not care about how I ordered my it calls relative to the describe call in the top level describe. It executes top test1, top test2 and then the sublevel tests, even though the order I gave was top test1, then the sublevel tests and then top test2.

What you want to use among before, beforeEach, etc. really depends on the specifics of your tests. If you need to setup a mock object or data structure and this object or structure can be reused by all the tests in a single describe, you can use before to set it up, and after to tear it down. This could be the case if you are doing read-only tests on the structure. If all your tests only read it, then there is no need to create it over and over. If each test in your describe needs a new copy of the structure because each test is modifying the structure then you should use beforeEach to create the structure anew for each test and then afterEach if you need to tear it down cleanly. Doing this ensures test isolation: each test starts from a known state and does not depend on the presence or absence of a previous test to succeed.

like image 52
Louis Avatar answered Oct 23 '22 01:10

Louis