Skip to content

/commands/bun/bun-test

bun test: run tests with Bun's built-in test runner

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
Bun
versions
Bun 1.x
os
any

bun test runs every test file in the project with Bun's built-in runner: files named *.test.{js,jsx,ts,tsx}, *_test.*, *.spec.* or *_spec.*. Tests import test, expect, describe and the hooks from bun:test, an API compatible with Jest. TypeScript works without configuration. The command exits 0 when every test passes and 1 when any test fails.

Example

bash
cat > math.ts <<'EOF'
export const add = (a: number, b: number) => a + b;
EOF
cat > math.test.ts <<'EOF'
import { describe, expect, test } from "bun:test";
import { add } from "./math";

describe("add", () => {
  test("adds two numbers", () => {
    expect(add(1, 2)).toBe(3);
  });
  test("is wrong on purpose", () => {
    expect(add(2, 2)).toBe(5);
  });
});
EOF
npx --yes bun@1 test 2>&1 | grep -E "^\((pass|fail)\)|^ *[0-9]+ (pass|fail)$|^Expected|^Received" | sed -E 's/ \[[0-9.]+m?s\]$//'
exit "${PIPESTATUS[0]}"

Output · exit 1

(pass) add > adds two numbers
Expected: 5
Received: 4
(fail) add > is wrong on purpose
 1 pass
 1 fail

The full output also shows the failing line with a caret under the assertion. In CI, the non-zero exit code fails the job.

Common options

CommandEffect
bun test mathRun only test files whose path contains "math"
bun test -t "adds two"Run only tests whose name matches the pattern (--test-name-pattern)
bun test --watchRe-run on file changes
bun test --coveragePrint a coverage table (--coverage-reporter=lcov writes lcov.info)
bun test --bailStop after the first failure
bun test --timeout 10000Per-test timeout in milliseconds (default 5000)
bun test --update-snapshotsRewrite toMatchSnapshot() snapshots
bun test --rerun-each 10Run each test 10 times to find flaky tests

bun test is a built-in command: if package.json has a "test" script (for example one that runs Vitest), bun test still starts Bun's runner. Use bun run test to run the script.

Writing tests

The API mirrors Jest, imported from bun:test instead of being global:

APIUse
test / it, describeDefine tests and group them
beforeAll, beforeEach, afterEach, afterAllSet up and tear down state around tests
test.skip, test.todoSkip a test, or mark one as planned; run todo tests with --todo
expect(x).toBe / toEqual / toThrowAssertions with Jest-compatible matchers
mock(fn) or jest.fn(fn)Create a mock function and assert on its calls with toHaveBeenCalled
expect(x).toMatchSnapshot()Snapshot testing; snapshots are stored next to the test file

Behaviour to know

  • One process by default. Bun loads every test file in a single process with shared globals, which is fast but means a test that changes global state can affect another file. --parallel runs files in separate worker processes, one per CPU core by default.
  • Concurrency is opt-in. Tests inside a file run one after the other; --concurrent runs async tests in parallel (20 at a time by default, change with --max-concurrency).
  • CI integration. Inside GitHub Actions, bun test detects the environment and emits annotations for failures; --reporter=junit writes an XML report for other systems.
  • Types are not checked by default. Like bun run, the runner strips TypeScript types. Recent Bun versions type-check the tests in the same step with bun test --check; otherwise run tsc --noEmit separately.

FAQ

Can bun test run my existing Jest tests?

Often, yes: bun:test provides describe, test, expect, lifecycle hooks, snapshots and mocks with Jest-style names, and jest.fn() works as an alias of mock(). Bun aims for Jest compatibility but has not implemented everything, so run the suite and check the failures.

Why does bun test ignore my Vitest config?

bun test is Bun's own runner and does not read vitest.config or jest.config files. To keep using Vitest, run it through your package.json script with bun run test.

How do I get a JUnit report for CI?

Use bun test --reporter=junit --reporter-outfile=./bun.xml. Bun still prints the normal output and writes the XML file for GitLab, Jenkins and similar tools.

Sources