Global beforeEach and afterEach in protractor

2019-06-20 04:45发布

问题:

In each spec I have beforeEach and afterEach statements. Is it possible to add it somehow globally to avoid code duplication between specs ?

回答1:

Purpose of beforeEach() and afterEach() functions are to add a block of repetitive code that you would need to execute every time you start or complete executing each spec(it). There are other ways to add generalised code to avoid code repetition, here are few -

  • If you have a piece of code that you would require to run only once before starting a test suite(describe), then you can use beforeAll() and afterAll() functions that jasmine provides.
  • If you want to run a piece of code that you want to run only once when the execution starts before starting all the test scripts, then add it in your onPrepare() and onComplete() function.
  • If you want to add a piece of code that should run even before protractor has started instantiating itself or after it has shut itself down, then use beforeLaunch and afterLaunch.

So it all depends on the scenario that you want to use them in. Hope it helps.



回答2:

My team has the same desire, to run bits of boilerplate code at the start of every test file. From the discussion here, it doesn't sound like there are hooks to globally add to the beforeEach(), afterEach(), etc.

However, we do use the onPrepare() function to abbreviate the amount of before/after boilerplate code that gets repeated in each spec file. Below is a beforeAll() example, but the pattern could be used for beforeEach()/afterEach(). In this case, we're setting up test users in the database with a DataSeeder class, which we do in the outer-most describe() block in every spec file. (I'm also leaving in my catchProtractorErrorInLocation pattern, because it's super useful for us.)

In protractor.conf.ts add boilerplate code to browser.params object.

  onPrepare: function () {
    ...
    const browser = require('protractor').browser;
    // Define the ConsoleHelper & DataSeeder instances, which will be used by all tests.
    const DataSeeder = require('./e2e/support/data-seeder.js');
    browser.params.dataSeeder = new DataSeeder();

    browser.catchProtractorErrorInLocation = (error, location) => {
      throw new Error(`Error in ${location}\n     ${error}`);
    };
    browser.catchProtractorErrorInBeforeAll = (error) => browser.catchProtractorErrorInLocation(error, 'beforeAll()');

    // Return a promise that resolves when DataSeeder is connected to service and ready to go
    return browser.params.dataSeeder.waitForConnect();
  },

With that in place, we can easily do beforeAll() setup code in an abbreviated set of lines.

  beforeAll(() => {
    return browser.params.dataSeeder.createTestUsers()
      .catch(browser.catchProtractorErrorInBeforeAll);
  });

You obviously need to do different things in your setup, but you can see how the pattern can apply.