skills/bun-test-configuration/SKILL.md
Learn how to configure Bun test behavior using bunfig.toml and command-line options
npx skillsauth add jarle/bun-skills Bun Test configurationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Learn how to configure Bun test behavior using bunfig.toml and command-line options
Configure bun test via bunfig.toml file and command-line options. This page documents the available configuration options for bun test.
You can configure bun test behavior by adding a [test] section to your bunfig.toml file:
[test]
# Options go here
The root option specifies a root directory for test discovery, overriding the default behavior of scanning from the project root.
[test]
root = "src" # Only scan for tests in the src directory
This is useful when you want to:
[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
Load scripts before running tests using the preload option:
[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
// Global test setup
import { beforeAll, afterAll } from "bun:test";
beforeAll(() => {
// Set up test database
setupTestDatabase();
});
afterAll(() => {
// Clean up
cleanupTestDatabase();
});
// 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" })),
}));
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:
// 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
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
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"]
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:
bun test --smol
The smol mode reduces memory usage by:
This is useful for:
Automatically run test files matching a glob pattern with concurrent test execution enabled. This is useful for gradually migrating test suites to concurrent execution or for running specific test types concurrently.
[test]
concurrentTestGlob = "**/concurrent-*.test.ts" # Run files matching this pattern concurrently
Test files matching this pattern will behave as if the --concurrent flag was passed, running all tests within those files concurrently. This allows you to:
The --concurrent CLI flag will override this setting when specified, forcing all tests to run concurrently regardless of the glob pattern.
Run tests in random order to identify tests with hidden dependencies:
[test]
randomize = true
Specify a seed for reproducible random test order. Requires randomize = true:
[test]
randomize = true
seed = 2444615283
Default retry count for all tests. Failed tests will be retried up to this many times. Per-test { retry: N } overrides this value. Default 0 (no retries).
[test]
retry = 3
The --retry CLI flag will override this setting when specified.
Re-run each test file multiple times to identify flaky tests:
[test]
rerunEach = 3
[test]
# Enable coverage by default
coverage = true
# Set coverage reporter
coverageReporter = ["text", "lcov"]
# Set coverage output directory
coverageDir = "./coverage"
Exclude files matching test patterns (e.g., *.test.ts) from the coverage report:
[test]
coverageSkipTestFiles = true # Exclude test files from coverage reports
The coverage threshold can be specified either as a number or as an object with specific 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.
[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
}
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 will be excluded from coverage calculation and reporting. See the coverage documentation for more details and examples.
[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/**"
]
Internally, Bun transpiles every file. That means code coverage must also go through sourcemaps before they can be reported. We expose this as a flag to allow you to opt out of this behavior, but it will be confusing because during the transpilation process, Bun may move code around and change variable names. This option is mostly useful for debugging coverage issues.
[test]
coverageIgnoreSourcemaps = true # Don't use sourcemaps for coverage analysis
<Warning>
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.
</Warning>
The bun test command inherits relevant network and installation configuration (registry, cafile, prefer, exact, etc.) from the [install] section of bunfig.toml. This is important if tests need to interact with private registries or require specific install behaviors triggered during the test 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 for tests should be set using .env files. Bun automatically loads .env files from your project root. 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
Here's a comprehensive example showing all 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"]
# 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"
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
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
Bun will warn about invalid configuration options:
[test]
invalidOption = true # This will generate a warning
[test]
# Correct
timeout = 10000
# Incorrect - will be treated as string
timeout = "10000"
To see what configuration is being used:
# Show effective configuration
bun test --dry-run
# Verbose output to see configuration loading
bun test --verbose
development
Using TypeScript with Bun, including type definitions and compiler options
development
Learn how to write tests using Bun's Jest-compatible API with support for async tests, timeouts, and various test modifiers
testing
Learn how to use snapshot testing in Bun to save and compare output between test runs
testing
Learn about Bun test's runtime integration, environment variables, timeouts, and error handling