rembrembdocs

Always enable coverage

coverage = true


By default coverage reports will include test files and exclude sourcemaps. This is usually what you want, but it can be configured otherwise in `bunfig.toml`.

bunfig.toml

[test] coverageSkipTestFiles = true # default false


## Coverage Thresholds

It is possible to specify a coverage threshold in `bunfig.toml`. If your test suite does not meet or exceed this threshold, `bun test` will exit with a non-zero exit code to indicate the failure.

### Simple Threshold

bunfig.toml

[test]

To require 90% line-level and function-level coverage

coverageThreshold = 0.9


### Detailed Thresholds

bunfig.toml

[test]

To set different thresholds for lines and functions

coverageThreshold = { lines = 0.9, functions = 0.9, statements = 0.9 }


Setting any of these thresholds enables `fail_on_low_coverage`, causing the test run to fail if coverage is below the threshold.

## Coverage Reporters

By default, coverage reports will be printed to the console. For persistent code coverage reports in CI environments and for other tools, you can pass a `--coverage-reporter=lcov` CLI option or `coverageReporter` option in `bunfig.toml`.

bunfig.toml

[test] coverageReporter = ["text", "lcov"] # default ["text"] coverageDir = "path/to/somewhere" # default "coverage"


### Available Reporters

Reporter

Description

`text`

Prints a text summary of the coverage to the console

`lcov`

Save coverage in lcov format

### LCOV Coverage Reporter

To generate an lcov report, you can use the lcov reporter. This will generate an `lcov.info` file in the coverage directory.

bunfig.toml

[test] coverageReporter = "lcov"


terminal

Or via CLI

bun test --coverage --coverage-reporter=lcov


The LCOV format is widely supported by various tools and services:

*   **Code editors**: VS Code extensions can show coverage inline
*   **CI/CD services**: GitHub Actions, GitLab CI, CircleCI
*   **Coverage services**: Codecov, Coveralls
*   **IDEs**: WebStorm, IntelliJ IDEA

#### Using LCOV with GitHub Actions

.github/workflows/test.yml

name: Test with Coverage on: [push, pull_request]

jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v2 - run: bun install - run: bun test --coverage --coverage-reporter=lcov - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: file: ./coverage/lcov.info


## Excluding Files from Coverage

### Skip Test Files

By default, test files themselves are included in coverage reports. You can exclude them with:

bunfig.toml

[test] coverageSkipTestFiles = true # default false


This will exclude files matching test patterns (e.g., `*.test.ts`, `*.spec.js`) from the coverage report.

### Ignore Specific Paths and Patterns

You can exclude specific files or file patterns from coverage reports using `coveragePathIgnorePatterns`:

bunfig.toml

[test]

Single pattern

coveragePathIgnorePatterns = "**/*.spec.ts"

Multiple patterns

coveragePathIgnorePatterns = [ "/*.spec.ts", "/.test.ts", "src/utils/**", ".config.js" ]


This option accepts glob patterns and works similarly to Jest’s `collectCoverageFrom` ignore patterns. Files matching any of these patterns will be excluded from coverage calculation and reporting in both text and LCOV outputs.

#### Common Use Cases

bunfig.toml

[test] coveragePathIgnorePatterns = [

Exclude utility files

"src/utils/**",

Exclude configuration files

"*.config.js", "webpack.config.ts", "vite.config.ts",

Exclude specific test patterns

"/*.spec.ts", "/*.e2e.ts",

Exclude build artifacts

"dist/", "build/",

Exclude generated files

"src/generated/", "/*.generated.ts",

Exclude vendor/third-party code

"vendor/", "third-party/" ]


## Sourcemaps

Internally, Bun transpiles all files by default, so Bun automatically generates an internal source map that maps lines of your original source code onto Bun’s internal representation. If for any reason you want to disable this, set `test.coverageIgnoreSourcemaps` to `true`; this will rarely be desirable outside of advanced use cases.

bunfig.toml

[test] coverageIgnoreSourcemaps = true # default false


## Coverage Defaults

By default, coverage reports:

*   **Exclude** `node_modules` directories
*   **Exclude** files loaded via non-JS/TS loaders (e.g., `.css`, `.txt`) unless a custom JS loader is specified
*   **Include** test files themselves (can be disabled with `coverageSkipTestFiles = true`)
*   Can exclude additional files with `coveragePathIgnorePatterns`

## Advanced Configuration

### Custom Coverage Directory

bunfig.toml

[test] coverageDir = "coverage-reports" # default "coverage"


### Multiple Reporters

bunfig.toml

[test] coverageReporter = ["text", "lcov"]


### Coverage with Specific Test Patterns

terminal

Run coverage only on specific test files

bun test --coverage src/components/*.test.ts

Run coverage with name pattern

bun test --coverage --test-name-pattern="API"


## CI/CD Integration

### GitHub Actions Example

.github/workflows/coverage.yml

name: Coverage Report on: [push, pull_request]

jobs: coverage: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4

  - name: Setup Bun
    uses: oven-sh/setup-bun@v2

  - name: Install dependencies
    run: bun install

  - name: Run tests with coverage
    run: bun test --coverage --coverage-reporter=lcov

  - name: Upload to Codecov
    uses: codecov/codecov-action@v3
    with:
      file: ./coverage/lcov.info
      fail_ci_if_error: true

### GitLab CI Example

.gitlab-ci.yml

test:coverage: stage: test script: - bun install - bun test --coverage --coverage-reporter=lcov coverage: '/Lines\s*:\s*(\d+.\d+)%/' artifacts: reports: coverage_report: coverage_format: cobertura path: coverage/lcov.info


## Interpreting Coverage Reports

### Text Output Explanation

-------------|---------|---------|-------------------

File% Funcs% LinesUncovered Line #s
All files85.7190.48
src/85.7190.48
utils.ts100.00100.00
api.ts75.0085.7115-18,25
main.ts80.0088.8942,50-52
--------------------------------------------------

*   **% Funcs**: Percentage of functions that were called during tests
*   **% Lines**: Percentage of executable lines that were run during tests
*   **Uncovered Line #s**: Specific line numbers that were not executed

### What to Aim For

*   **80%+ overall coverage**: Generally considered good
*   **90%+ critical paths**: Important business logic should be well-tested
*   **100% utility functions**: Pure functions and utilities are easy to test completely
*   **Lower coverage for UI components**: Often acceptable as they may require integration tests

## Best Practices

### Focus on Quality, Not Just Quantity

![https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z\_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z\_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b](https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b)test.ts

// Good: Test actual functionality test("calculateTax should handle different tax rates", () => { expect(calculateTax(100, 0.08)).toBe(8); expect(calculateTax(100, 0.1)).toBe(10); expect(calculateTax(0, 0.08)).toBe(0); });

// Avoid: Just hitting lines for coverage test("calculateTax exists", () => { calculateTax(100, 0.08); // No assertions! });


### Test Edge Cases

![https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z\_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z\_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b](https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b)test.ts

test("user input validation", () => { // Test normal case expect(validateEmail("user@example.com")).toBe(true);

// Test edge cases that improve coverage meaningfully expect(validateEmail("")).toBe(false); expect(validateEmail("invalid")).toBe(false); expect(validateEmail(null)).toBe(false); });


### Use Coverage to Find Missing Tests

terminal

Run coverage to identify untested code

bun test --coverage

Look at specific files that need attention

bun test --coverage src/critical-module.ts


### Combine with Other Quality Metrics

Coverage is just one metric. Also consider:

*   **Code review quality**
*   **Integration test coverage**
*   **Error handling tests**
*   **Performance tests**
*   **Type safety**

## Troubleshooting

### Coverage Not Showing for Some Files

If files aren’t appearing in coverage reports, they might not be imported by your tests. Coverage only tracks files that are actually loaded.

![https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z\_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z\_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b](https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35b)test.ts

// Make sure to import the modules you want to test import { myFunction } from "../src/my-module";

test("my function works", () => { expect(myFunction()).toBeDefined(); });


### False Coverage Reports

If you see coverage reports that don’t match your expectations:

1.  Check if source maps are working correctly
2.  Verify file patterns in `coveragePathIgnorePatterns`
3.  Ensure test files are actually importing the code to test

### Performance Issues with Large Codebases

For large projects, coverage collection can slow down tests:

bunfig.toml

[test]

Exclude large directories you don't need coverage for

coveragePathIgnorePatterns = [ "node_modules/", "vendor/", "generated/**" ]


Consider running coverage only on CI or specific branches rather than every test run during development.