Some setup, like connecting to a test database or starting a server, is expensive and only needs to happen once. This lesson covers beforeAll() and afterAll(), which run a single time per scope instead of before/after every test.
beforeAll() and afterAll() Run Once Per Scope
beforeAll(fn) runs once, before any test in its scope executes. afterAll(fn) runs once, after every test in its scope has finished. This makes them ideal for expensive setup (connecting to a database, starting an in-memory server) and matching cleanup.
Because the setup only happens once, any state created in beforeAll() is shared across all tests in the scope — which means tests must not mutate that shared state in ways that would affect other tests.
The database connection opens once for the whole file and closes once at the end, instead of reconnecting for every test.
beforeAll/afterAll Syntax
beforeAll(async () => {
// runs once, before any test in this scope
});
afterAll(async () => {
// runs once, after all tests in this scope finish
});
Both accept synchronous or async functions, just like beforeEach()/afterEach().
Scoped inside a describe() block, they run once per block, not once per file.
Use them for expensive, shared resources: database connections, servers, temp files.
Combine with beforeEach() when you need both one-time setup and per-test resets.
beforeAll/afterAll Cheat Sheet
When to reach for each Jest lifecycle hook.
Hook
Frequency
Typical Use
beforeAll()
Once per scope
Open DB connection, start server
afterAll()
Once per scope
Close DB connection, stop server
beforeEach()
Before every test
Reset mocks, seed fresh data
afterEach()
After every test
Clear mocks, roll back a transaction
Combining beforeAll() with beforeEach()
A common, effective pattern: use beforeAll() to establish an expensive, shared connection once, and beforeEach() to reset or reseed data before each individual test so tests remain isolated from one another despite sharing the connection.
The connection opens once; the data resets before every test to keep tests independent.
File-Scoped vs. describe()-Scoped Hooks
When beforeAll()/afterAll() are declared inside a describe() block, they apply only to tests within that block, letting different sections of a large file each set up their own expensive resource independently.
Using beforeAll() for setup that must be fresh per test, causing tests to affect each other.
Forgetting afterAll() cleanup, leaving database connections or servers open after the suite finishes.
Not awaiting an async beforeAll(), causing tests to run against a connection that isn't ready yet.
Relying on test execution order for shared state instead of explicit setup in beforeEach().
Key Takeaways
beforeAll()/afterAll() run once per scope, ideal for expensive shared resources.
beforeEach()/afterEach() still run per test and can reset state on top of a one-time setup.
Scoping hooks inside describe() blocks isolates setup to just that section of tests.
Always close/cleanup expensive resources in afterAll() to avoid leaks between test files.
Pro Tip
If your beforeAll() setup is slow enough to notice, that's often a sign to consider an in-memory alternative (like an in-memory SQLite or Mongo instance) to keep your suite fast.
You now know when to use beforeAll() and afterAll(). Next, learn about global setup files for configuration shared across your whole test suite.