47

When writing tests with JasmineJS I have many tests that have similar beforeEach/afterEach code.

Is there a way to implement an inheritance model using JasmineJS test suites?

I can group all tests in a single describe but in this case I will end with a single HUGE JS file containing all tests.

I would like to split the tests for each page.

Here is an example:

describe('Services Page', function() {

    beforeEach(function() {
        login_as_admin()
    })

    beforeEach(function() {
        browser().navigateTo('/services')
    })

    if('Some test for services page', function() {})

    afterEach(function() {
        logout()
    })

})


describe('Administrators Page', function() {

    beforeEach(function() {
        login_as_admin()
    })

    beforeEach(function() {
        browser().navigateTo('/administrators')
    })

    if('Some test for administrators page', function() {})

    afterEach(function() {
        logout()
    })

})
Adi Roiban
  • 1,293
  • 2
  • 13
  • 28
  • 2
    will every page have `login_as_admin()` and `logout()`? – xst May 15 '14 at 17:47
  • Does this answer your question? [Global \`beforeEach\` in jasmine?](https://stackoverflow.com/questions/10560716/global-beforeeach-in-jasmine) – xianshenglu Jan 17 '23 at 12:45

5 Answers5

47

I think this is partially examined in this blog post and also answered here but i'm adding an adapted answer for your example:

Reusable code:

function sharedSetup(startPage) {
    beforeEach(function() {
        login_as_admin();
        browser().navigateTo(startPage);
    });

    afterEach(function() {
        logout();
    });
};

How to use it:

describe('Services Page', function() {
    sharedSetup('/services');

    it('Some test for services page', function() {});
});

describe('Administrators Page', function() {
    sharedSetup('/administrators');

    it('Some test for administrators page', function() {});
});
Community
  • 1
  • 1
Leo Gallucci
  • 16,355
  • 12
  • 77
  • 110
  • The updated link for the blog post is [here](https://tanzu.vmware.com/content/blog/drying-up-jasmine-specs-with-shared-behavior) and [here](http://web.archive.org/web/20141005190338/http://pivotallabs.com/drying-up-jasmine-specs-with-shared-behavior/) an old version with the missing code snippets. – Augusto Franzoia Apr 05 '20 at 11:40
22

If you want to do this for all your suites, you can register a beforeEach or afterEach function in the topSuite:

jasmine.getEnv().topSuite().beforeEach({fn: function() {
   //log in as admin
}});

If you only want to apply it on some suites, you can work with sub-suites:

describe("as_admin", function() {
  beforeEach(function() {
    //log in as admin
  });

  describe('Services Page',function() {...});
  describe('Administrators Page',function() {...});

}
Steven
  • 2,050
  • 23
  • 20
  • I think it is also possible to use: jasmine.getEnv().beforeEach(function () { //log in as admin }); based on tests included in changes here: https://github.com/jasmine/jasmine/issues/811 – rajsite Jun 22 '16 at 20:53
  • Looks like it's important to call `done()` callback in `beforeEach` as it hangs without it. – Vanuan Sep 27 '17 at 23:40
5

Jasmine does allow you to put beforeEach and afterEach outside of a describe call. In this way you can have setup and teardown that is global for all of your specs. Your logout() call seems like it might be a good candidate for global teardown, and if all of your specs login as an admin, you could move that out to global scope as well.

For things that are used in some, but not all, specs, having a method like your login_as_admin() seems like the best way to consolidate that logic in one place.

Gregg
  • 2,628
  • 1
  • 22
  • 27
1

Reference: (Pivotal Labs Blog:Davis W. Frank)

He describes collecting shared functionality in a function that is called with parameters for the different individual suites. Calling this function within each suite will execute the common setup/configuration.

As to splitting tests across files; the file with the shared function can either be included within each page with a <script> tag if the tests are browser based, or by a require(...) near the top if the tests are node based. You can then run the tests independently but using that shared setup which is defined only once.

xst
  • 2,536
  • 5
  • 29
  • 41
0

Found in the issues.

So in 3.7.0 afterEach along with other methods got moved out of Env namespace and into Globals.

the call in test.ts should be now:

afterEach(() => {});

that's it.

xianshenglu
  • 4,943
  • 3
  • 17
  • 34