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 usebeforeAll()
andafterAll()
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()
andonComplete()
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
andafterLaunch
.
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.