Per-test setup and teardown
UsebeforeEach and afterEach for setup and cleanup that should happen around every test:
Per-scope setup and teardown
UsebeforeAll and afterAll for setup and cleanup that should happen once for a group of tests. The scope is determined by where the hook is defined.
Scoped to a describe block
Scoped to a test file
Hooks defined at the top level of a file apply to all tests in that file:Global setup and teardown
To run hooks before any test file executes, define them in a preload file:setup.ts
bunfig.toml:
bunfig.toml
Async hooks
All hooks support async functions. Bun awaits each hook before proceeding.onTestFinished
UseonTestFinished to register a callback that runs after a specific test completes, after all afterEach hooks:
onTestFinished is not supported inside concurrent tests. Use test.serial for tests that need per-test cleanup via this hook.Execution order
When hooks are nested insidedescribe blocks, they run in this order:
Parameterized tests
test.each
Run the same test function with multiple inputs:describe.each
Create a parameterized suite — every test inside runs once per data set:Error handling
If a hook throws, all tests in its scope are skipped:Best practices
Match the hook scope to the resource lifetime
Match the hook scope to the resource lifetime
Use
beforeAll/afterAll for expensive shared resources (servers, database connections) and beforeEach/afterEach for per-test state (mock data, DOM resets).Always clean up resources
Always clean up resources
Failing to clean up can cause test pollution and flakiness:
Keep hooks simple
Keep hooks simple
Move complex setup logic into helper functions to keep hooks readable and testable: