Jasmine: Understanding the Difference between beforeAll and beforeEach

Chris Breazeal, December 19, 2015

The purpose of this article is to describe the behavior of the beforeAll and beforeEach functions in a Jasmine spec. beforeAll and beforeEach, along with afterAll and afterEach, are Jasmine global functions that can be used manage expensive setup and teardown in test suites.

Behavior

The beforeAll function executes once and only once for the describe block containing it, before any of the beforeEach functions or any of the specs.

The beforeEach function executes before any spec in the describe block containing it, as well as before any spec contained inside any inner describe. You'll see this in A More Complex Example below.

beforeAll has a complementary function in afterAll that is run once per describe after all specs contained therein are finished.

Likewise, the beforeEach function has a complementary afterEach function that is run after each spec.

afterAll and afterEach are used for whatever cleanup is needed at the conclusion of the specs, and are not covered as part of this document.

Simple Example

Consider the following test file. Notice that there is one describe, one beforeAll, one beforeEach, and two specs, i.e., it functions, with a console.log in each.


describe('A single describe', function() {
    beforeAll(function() {
        console.log('in beforeAll');
    });
    
    beforeEach(function() {
        console.log('in beforeEach');
    });
    
    it('spec A', function() {
        console.log('in spec A');
        expect(true).toBe(true);
    });
    
    it('spec B', function() {
        console.log('in spec B');
        expect(true).toBe(true);
    });
});
                        

Running the above test produces the following output:

log: in beforeAll
log: in beforeEach
log: in spec A
log: in beforeEach
log: in spec B
                        

Notice the beforeAll was called one time and the beforeEach was called once before each it.

A More Complex Example

Now let's increase the complexity of the test. Notice the following test has two describe blocks, one inside the other, with each describe containing a beforeAll, beforeEach, and two it functions.


describe('Outer describe', function () {
    beforeAll(function () {
        console.log('in outer beforeAll');
    });

    beforeEach(function () {
        console.log('in outer beforeEach');
    });

    it('spec A', function () {
        console.log('in spec A');
        expect(true).toBe(true);
    });

    it('spec B', function () {
        console.log('in spec B');
        expect(true).toBe(true);
    });

    describe('inner describe', function () {
        beforeAll(function () {
            console.log('in inner beforeAll');
        });

        beforeEach(function () {
            console.log('in inner beforeEach');
        });

        it('spec C', function () {
            console.log('in spec A');
            expect(true).toBe(true);
        });

        it('spec D', function () {
            console.log('in spec B');
            expect(true).toBe(true);
        });
    });
});
                        

Running the above test produces the following output:

log: in outer beforeAll
log: in outer beforeEach
log: in spec A
log: in outer beforeEach
log: in spec B
log: in inner beforeAll
log: in outer beforeEach
log: in inner beforeEach
log: in spec C
log: in outer beforeEach
log: in inner beforeEach
log: in spec D
                        

Carefully observe the results. Notice that the 'outer' beforeAll was executed only once, as we expected, and the 'inner' beforeAll was also executed once, but after the two 'outer' specs.

But look at the beforeEach. For spec A and spec B, only the outer beforeEach was fired before those tests. However, for spec C and spec D, both the 'outer' and 'inner' beforeEach are fired before each of those specs.

Conclusion

Knowing the difference between beforeAll and beforeEach allows the programmer to not only optimize the tests by placing setup code in a beforeAll or a beforeEach as needed, but provides the added benefit DRYing up duplicated setup code. Understanding when the beforeAll and beforeEach functions are called in relation to each other and within nested describe blocks provides opportunities for success, but lack of understanding provides opportunities for confusing failure.

One word of caution however. Use the afterAll and afterEach properly to ensure state is not leaked between specs.

Reach Chris at

chris@breazeal.com
Chris @ Linkedin
Tweet