What beforeAll() and afterAll() Do
beforeAll() registers a function that Jest runs exactly once before any test in its scope executes, and afterAll() runs exactly once after all tests in that scope have finished. They're designed for expensive, one-time setup and teardown rather than per-test resets.
Cricket analogy: beforeAll() is like setting up the entire stadium's floodlights and pitch cover once before a full day-night Test match begins, not before every single delivery bowled during the day.
One-Time Teardown with afterAll()
afterAll() is the natural counterpart to beforeAll(): it releases whatever expensive resource was acquired once, such as closing a database connection pool, shutting down a mock server, or disconnecting a shared client, after every test in the scope has completed.
Cricket analogy: afterAll() closing a database connection once after all tests finish is like removing the stumps and covering the pitch once after the entire Test match series ends, not after each day's play.
describe('database integration', () => {
let connection;
beforeAll(async () => {
connection = await createTestDbConnection();
await connection.migrate();
});
afterAll(async () => {
await connection.close();
});
beforeEach(async () => {
await connection.clearTable('users');
});
test('inserts a user record', async () => {
await connection.insert('users', { name: 'Ravi' });
const rows = await connection.query('SELECT * FROM users');
expect(rows).toHaveLength(1);
});
});The Risk of Shared State
Because a resource created in beforeAll() is shared across every test in the scope, mutations made by one test — like inserting a row or changing a cached value — persist and can silently affect later tests unless you actively reset the relevant state, typically inside beforeEach().
Cricket analogy: Sharing a single database connection across tests via beforeAll() is like an entire tour squad sharing one team bus set up once for the tour, which is efficient but means if the bus breaks down, every match is affected, unlike per-match transport.
Because beforeAll() runs its resource setup only once, tests that mutate that shared resource (like inserting rows into a shared test database) can pollute one another unless you clear or reset the relevant data in beforeEach() as well.
beforeAll() and afterAll() also accept async functions, which is essential for real setup like spinning up an in-memory MongoDB instance with mongodb-memory-server once for a whole test file.
- beforeAll() runs once before all tests in its scope; afterAll() runs once after all tests finish.
- Use beforeAll()/afterAll() for expensive setup like database connections or server instances.
- Shared state from beforeAll() persists across tests, so mutations in one test can affect another.
- Combine beforeAll() for connection setup with beforeEach() for per-test data resets.
- beforeAll()/afterAll() support async functions for real I/O like migrations or server startup.
- Overusing beforeAll() for mutable state trades speed for test isolation risk.
Practice what you learned
1. What is the key difference between beforeAll() and beforeEach()?
2. Why might inserting rows into a database connection created in beforeAll() cause flaky tests?
3. Which hook is best suited for shutting down a shared test server once all tests complete?
4. Can beforeAll() accept an async function?
5. What is a common pattern combining beforeAll() and beforeEach()?
Was this page helpful?
You May Also Like
beforeEach() and afterEach()
Learn how Jest's beforeEach() and afterEach() hooks establish and tear down consistent test state so every test runs in isolation.
Test Fixtures and Factories
Learn how to build reusable test fixtures and factory functions to generate consistent, customizable test data across a Jest suite.