Configure bun test with bunfig.toml and command-line options.
Configuration File
To configure bun test in bunfig.toml, add a [test] section:
Test Discovery
root
The root option sets the directory Bun scans for tests, instead of the project root.
[test]
root = "src" # Only scan for tests in the src directory
Examples
[test]
# Only run tests in the src directory
root = "src"
# Run tests in a specific test directory
root = "tests"
# Run tests in multiple specific directories (not currently supported - use patterns instead)
# root = ["src", "lib"] # This syntax is not supported
Preload Scripts
The preload option loads scripts before the tests run:
[test]
preload = ["./test-setup.ts", "./global-mocks.ts"]
This is equivalent to using --preload on the command line:
bun test --preload ./test-setup.ts --preload ./global-mocks.ts
Common Preload Use Cases
test-setup.ts// Global test setup
import { beforeAll, afterAll } from "bun:test";
beforeAll(() => {
// Set up test database
setupTestDatabase();
});
afterAll(() => {
// Clean up
cleanupTestDatabase();
});
global-mocks.ts// Global mocks
import { mock } from "bun:test";
// Mock environment variables
process.env.NODE_ENV = "test";
process.env.API_URL = "http://localhost:3001";
// Mock external dependencies
mock.module("./external-api", () => ({
fetchData: mock(() => Promise.resolve({ data: "test" })),
}));
Path Ignore Patterns
pathIgnorePatterns excludes files and directories from test discovery entirely, using glob patterns. Unlike coveragePathIgnorePatterns, which only affects coverage reports, pathIgnorePatterns prevents matching paths from being discovered and run as tests.
Use it when your project contains submodules, vendored code, or other directories with *.test.ts files that you don’t want bun test to pick up.
[test]
# Single pattern
pathIgnorePatterns = "vendor/**"
# Multiple patterns
pathIgnorePatterns = [
"vendor/**",
"submodules/**",
"fixtures/**"
]
This is equivalent to using --path-ignore-patterns on the command line:
bun test --path-ignore-patterns 'vendor/**' --path-ignore-patterns 'fixtures/**'
Bun prunes directories matching a pattern during scanning and never traverses their contents, so ignoring a large directory tree is cheap.
Common Use Cases
[test]
pathIgnorePatterns = [
# Git submodules with their own test suites
"submodules/**",
# Vendored dependencies
"vendor/**",
"third-party/**",
# Test fixtures that look like tests but aren't
"fixtures/**",
"**/test-data/**",
# Integration / E2E tests you want to run separately
"**/integration/**",
"e2e/**"
]
Command-line --path-ignore-patterns flags override the bunfig.toml value entirely — the two are not merged.
Timeouts
Default Timeout
Set the default timeout for all tests:
[test]
timeout = 10000 # 10 seconds (default is 5000ms)
This applies to all tests unless overridden by individual test timeouts:
test.ts// This test will use the default timeout from bunfig.toml
test("uses default timeout", () => {
// test implementation
});
// This test overrides the default timeout
test("custom timeout", () => {
// test implementation
}, 30000); // 30 seconds
Reporters
JUnit Reporter
Configure the JUnit reporter output file path directly in the config file:
[test.reporter]
junit = "path/to/junit.xml" # Output path for JUnit XML report
This complements the --reporter=junit and --reporter-outfile CLI flags:
# Equivalent command line usage
bun test --reporter=junit --reporter-outfile=./junit.xml
Multiple Reporters
You can use multiple reporters simultaneously:
# CLI approach
bun test --reporter=junit --reporter-outfile=./junit.xml
# Config file approach
[test.reporter]
junit = "./reports/junit.xml"
[test]
# Also enable coverage reporting
coverage = true
coverageReporter = ["text", "lcov"]
Memory Usage
smol Mode
Enable the --smol memory-saving mode specifically for the test runner:
[test]
smol = true # Reduce memory usage during test runs
This is equivalent to using the --smol flag on the command line:
The smol mode reduces memory usage by:
- Using less memory for the JavaScript heap
- Being more aggressive about garbage collection
- Reducing buffer sizes where possible
Use it in memory-constrained environments, such as CI runners, or for large test suites.
Test execution
concurrentTestGlob
Run test files matching a glob pattern with concurrent test execution enabled.
[test]
concurrentTestGlob = "**/concurrent-*.test.ts" # Run files matching this pattern concurrently
Test files matching the pattern behave as if the --concurrent flag was passed: every test in those files runs concurrently. Use this to migrate a test suite to concurrent execution gradually, or to run one kind of test (say, integration tests) concurrently while the rest stay sequential.
The --concurrent CLI flag overrides this setting, forcing all tests to run concurrently regardless of the glob pattern.
randomize
Run tests in random order to identify tests with hidden dependencies:
seed
Specify a seed for reproducible random test order. Requires randomize = true:
[test]
randomize = true
seed = 2444615283
retry
Default retry count for all tests. Bun retries a failed test up to this many times. Per-test { retry: N } overrides this value. Default 0 (no retries).
The --retry CLI flag overrides this setting.
rerunEach
Re-run each test file multiple times to identify flaky tests:
Coverage Options
Basic Coverage Settings
[test]
# Enable coverage by default
coverage = true
# Set coverage reporter
coverageReporter = ["text", "lcov"]
# Set coverage output directory
coverageDir = "./coverage"
Skip Test Files from Coverage
Exclude files matching test patterns (for example *.test.ts) from the coverage report:
[test]
coverageSkipTestFiles = true # Exclude test files from coverage reports
Coverage Thresholds
Specify the coverage threshold as a single number or as an object with per-metric thresholds:
[test]
# Simple threshold - applies to lines, functions, and statements
coverageThreshold = 0.8
# Detailed thresholds
coverageThreshold = { lines = 0.9, functions = 0.8, statements = 0.85 }
Setting any of these enables fail_on_low_coverage, causing the test run to fail if coverage is below the threshold.
Threshold Examples
[test]
# Require 90% coverage across the board
coverageThreshold = 0.9
# Different requirements for different metrics
coverageThreshold = {
lines = 0.85, # 85% line coverage
functions = 0.90, # 90% function coverage
statements = 0.80 # 80% statement coverage
}
Coverage Path Ignore Patterns
Exclude specific files or file patterns from coverage reports using glob patterns:
[test]
# Single pattern
coveragePathIgnorePatterns = "**/*.spec.ts"
# Multiple patterns
coveragePathIgnorePatterns = [
"**/*.spec.ts",
"**/*.test.ts",
"src/utils/**",
"*.config.js",
"generated/**",
"vendor/**"
]
Files matching any of these patterns are excluded from coverage calculation and reporting. See Code coverage.
Common Ignore Patterns
[test]
coveragePathIgnorePatterns = [
# Test files
"**/*.test.ts",
"**/*.spec.ts",
"**/*.e2e.ts",
# Configuration files
"*.config.js",
"*.config.ts",
"webpack.config.*",
"vite.config.*",
# Build output
"dist/**",
"build/**",
".next/**",
# Generated code
"generated/**",
"**/*.generated.ts",
# Vendor/third-party
"vendor/**",
"third-party/**",
# Utilities that don't need testing
"src/utils/constants.ts",
"src/types/**"
]
Sourcemap Handling
Bun transpiles every file, so coverage results pass through sourcemaps before they’re reported. coverageIgnoreSourcemaps opts out of this, but the results will be confusing: during transpilation, Bun may move code around and rename variables. The option is mostly useful for debugging coverage issues.
[test]
coverageIgnoreSourcemaps = true # Don't use sourcemaps for coverage analysis
When using this option, you probably want to stick a // @bun comment at the top of the source file to opt out of the
transpilation process.
Install Settings Inheritance
bun test inherits network and installation configuration (such as registry, cafile, prefer, and exact) from the [install] section of bunfig.toml. This matters if your tests reach a private registry or trigger installs during the run.
[install]
# These settings are inherited by bun test
registry = "https://npm.company.com/"
exact = true
prefer = "offline"
[test]
# Test-specific configuration
coverage = true
timeout = 10000
Environment Variables
Set environment variables for tests with .env files, which Bun loads from your project root automatically. For test-specific variables, create a .env.test file:
NODE_ENV=test
DATABASE_URL=postgresql://localhost:5432/test_db
LOG_LEVEL=error
Then load it with --env-file:
bun test --env-file=.env.test
Complete Configuration Example
An example showing the available test configuration options:
[install]
# Install settings inherited by tests
registry = "https://registry.npmjs.org/"
exact = true
[test]
# Test discovery
root = "src"
preload = ["./test-setup.ts", "./global-mocks.ts"]
pathIgnorePatterns = ["vendor/**", "submodules/**"]
# Execution settings
timeout = 10000
smol = true
# Coverage configuration
coverage = true
coverageReporter = ["text", "lcov"]
coverageDir = "./coverage"
coverageThreshold = { lines = 0.85, functions = 0.90, statements = 0.80 }
coverageSkipTestFiles = true
coveragePathIgnorePatterns = [
"**/*.spec.ts",
"src/utils/**",
"*.config.js",
"generated/**"
]
# Advanced coverage settings
coverageIgnoreSourcemaps = false
# Reporter configuration
[test.reporter]
junit = "./reports/junit.xml"
CLI Override Behavior
Command-line options always override configuration file settings:
[test]
timeout = 5000
coverage = false
# These CLI flags override the config file
bun test --timeout 10000 --coverage
# timeout will be 10000ms and coverage will be enabled
Conditional Configuration
You can use different configurations for different environments:
[test]
# Default test configuration
coverage = false
timeout = 5000
# Override for CI environment
[test.ci]
coverage = true
coverageThreshold = 0.8
timeout = 30000
Then in CI:
# Use CI-specific settings
bun test --config=ci
Validation and Troubleshooting
Invalid Configuration
Bun warns about invalid configuration options:
[test]
invalidOption = true # This will generate a warning
Common Configuration Issues
- Path Resolution: Relative paths in config are resolved relative to the config file location
- Pattern Matching: Glob patterns use standard glob syntax
- Type Mismatches: Ensure numeric values are not quoted unless they should be strings
[test]
# Correct
timeout = 10000
# Incorrect - will be treated as string
timeout = "10000"
Debugging Configuration
To see what configuration is being used:
# Show effective configuration
bun test --dry-run
# Verbose output to see configuration loading
bun test --verbose