# Bootstrap
In case you need to execute arbitrary code before or after the tests,
you can use the bootstrap
and teardown
config. Use it to start and stop a webserver, Selenium, etc.
When using the parallel execution mode, there are two additional hooks available; bootstrapAll
and teardownAll
. See bootstrapAll & teardownAll for more information.
β In CodeceptJS 2 bootstrap could be set as a function with
done
parameter. This way of handling async function was replaced with native async functions in CodeceptJS 3.
# Example: Bootstrap & Teardown
If you are using JavaScript-style config codecept.conf.js
, bootstrap and teardown functions can be placed inside of it:
var server = require('./app_server');
exports.config = {
tests: "./*_test.js",
helpers: {},
// adding bootstrap/teardown
async bootstrap() {
await server.launch();
},
async teardown() {
await server.stop();
}
// ...
// other config options
}
# BootstrapAll & TeardownAll
There are two additional hooks for parallel execution in run-multiple
or run-workers
commands.
These hooks are only called in the parent process. Before child processes start (bootstrapAll
) and after all of runs have finished (teardownAll
). Each worker process will call bootstrap
& teardown
in their own process.
For example, when you run tests in 2 workers using the following command:
npx codeceptjs run-workers 2
First, bootstrapAll
is called. Then two bootstrap
runs in each of workers. Then tests in worker #1 ends and teardown
is called. Same for worker #2. Finally, teardownAll
runs in the main process.
The same behavior is set for
run-multiple
command
The bootstrapAll
and teardownAll
hooks are preferred to use for setting up common logic of tested project: to start the application server or database or to start webdriver's grid.
The bootstrap
and teardown
hooks are used for setting up each testing browser: to create unique cloud testing server connection or to create specific browser-related test data in database (like users with names with browsername in it).
# Example: BootstrapAll & TeardownAll Inside Config
Using JavaScript-style config codecept.conf.js
, bootstrapAll and teardownAll functions can be placed inside of it:
const fs = require('fs');
const tempFolder = process.cwd() + '/tmpFolder';
exports.config = {
tests: "./*_test.js",
helpers: {},
// adding bootstrapAll/teardownAll
async bootstrapAll() {
fs.mkdirSync(tempFolder);
},
async bootstrap() {
console.log('Do some pretty suite setup stuff');
},
async teardown() {
console.log('Cool, one of the workers have finished');
},
async teardownAll() {
console.log('All workers have finished running tests so we should clean up the temp folder');
fs.rmdirSync(tempFolder);
},
// ...
// other config options
}
# Combining Bootstrap & BootstrapAll
It is quite common that you expect that bootstrapAll and bootstrap will do the same thing. If an application server is already started in bootstrapAll
we should not run it again inside bootstrap
for each worker. To avoid code duplication we can run bootstrap script only when we are not inside a worker. And we will use NodeJS isMainThread
Workers API to detect that:
// inside codecept.conf.js
// detect if we are in a worker thread
const { isMainThread } = require('worker_threads');
async function startServer() {
// implement starting server logic here
}
async function stopServer() {
// and stop server too
}
exports.config = {
// codeceptjs config goes here
async bootstrapAll() {
await startServer();
},
async bootstrap() {
// start a server only if we are not in worker
if (isMainThread) return startServer();
}
async teardown() {
// start a server only if we are not in worker
if (isMainThread) return stopServer();
}
async teardownAll() {
await stopServer();
},
}