bun test is deeply integrated with Bun’s runtime. This integration is part of what makes bun test fast.
Environment Variables
NODE_ENV
bun test sets $NODE_ENV to "test" unless it’s already set in the environment or in .env files. Most test runners do the same.
NODE_ENV explicitly:
terminal
TZ (Timezone)
bun test uses UTC (Etc/UTC) as the time zone unless the TZ environment variable overrides it. This keeps date and time behavior consistent across machines.
terminal
Test Timeouts
Each test has a default timeout of 5000ms (5 seconds). Tests that exceed it fail.Global Timeout
Change the timeout globally with the--timeout flag:
terminal
Per-Test Timeout
Set a per-test timeout as the third argument to the test function:Infinite Timeout
Use0 or Infinity to disable the timeout:
Error Handling
Unhandled Errors
bun test tracks unhandled promise rejections and errors that occur between tests. If any occur, the final exit code is non-zero, even if all tests pass.
This helps catch errors in asynchronous code that might otherwise go unnoticed:
Promise Rejections
Unhandled promise rejections are also caught:Custom Error Handling
You can set up custom error handlers in your test setup:CLI Flags Integration
Several Bun CLI flags also work withbun test:
Memory Usage
terminal
Debugging
terminal
Module Loading
terminal
Installation-related Flags
Watch and Hot Reloading
Watch Mode
With the--watch flag, the test runner watches for file changes and re-runs tests.
terminal
Hot Reloading
The--hot flag is similar, but more aggressive about preserving state between runs:
terminal
--watch: it gives better isolation between runs.
Global Variables
The following globals are available in test files without importing:Process Integration
Exit Codes
bun test uses standard exit codes:
0: All tests passed, no unhandled errors1: Test failures or unhandled errors occurred
Signal Handling
The test runner handles common signals:terminal
Environment Detection
Bun automatically detects certain environments and adjusts behavior:Performance Considerations
Single Process
The test runner runs all tests in a single process by default. This provides:- Faster startup - No need to spawn multiple processes
- Shared memory - Efficient resource usage
- Simple debugging - All tests in one process
- Tests share global state (use lifecycle hooks to clean up)
- One test crash can affect others
- No true parallelization of individual tests
Memory Management
terminal