bun:test module. All test functions (test, describe, expect, beforeAll, etc.) are also available as globals — no import required — for full Jest compatibility.
Basic usage
math.test.ts
Grouping tests
Usedescribe() to group related tests into a suite:
math.test.ts
Async tests
Tests can be async. Bun awaits the returned promise before marking the test as complete.done callback. If you declare it as a parameter, you must call it or the test will time out.
Timeouts
Pass a timeout in milliseconds as the third argument totest(). The default is 5000ms.
Test modifiers
test.skip
Skip a test without deleting it. Skipped tests are not executed.test.todo
Mark a test as a planned but unimplemented case:bun test --todo to find any todo tests that are unexpectedly passing.
test.only
Run only the tests (or suites) marked with.only. Use bun test --only to enforce this.
test.if / test.skipIf / test.todoIf
Run, skip, or mark a test as todo based on a runtime condition:describe blocks, affecting all tests within.
test.failing
Usetest.failing to mark a test you know is currently broken. The test passes when it fails, and fails when it unexpectedly passes:
test.concurrent / test.serial
Control concurrency at the individual test level. See Test Runner for details.Assertion counting
Useexpect.assertions() to verify a specific number of assertions ran — essential for async code with conditional branches:
expect.hasAssertions() to require at least one assertion:
Retries and repeats
You cannot use both
retry and repeats on the same test.Parameterized tests
test.each
Run the same test with multiple sets of data:$key syntax:
describe.each
Create a parameterized suite that runs all its tests for each case:Format specifiers
| Specifier | Description |
|---|---|
%p | pretty-format |
%s | String |
%d | Number |
%i | Integer |
%f | Floating point |
%j | JSON |
%o | Object |
%# | Index of the test case |
%% | Literal % |
Type testing
Bun includesexpectTypeOf for type-level assertions, compatible with Vitest. These are no-ops at runtime — run bunx tsc --noEmit to validate types.
Matchers reference
Basic
| Matcher | Description |
|---|---|
.toBe() | Strict equality (===) |
.toEqual() | Deep equality |
.toStrictEqual() | Deep equality with type checks |
.toBeNull() | Value is null |
.toBeUndefined() | Value is undefined |
.toBeDefined() | Value is not undefined |
.toBeTruthy() | Value is truthy |
.toBeFalsy() | Value is falsy |
.toBeNaN() | Value is NaN |
.not | Negates the matcher |
Strings and arrays
| Matcher | Description |
|---|---|
.toContain() | String or array contains a value |
.toHaveLength() | Array or string has a specific length |
.toMatch() | String matches regex or substring |
.toContainEqual() | Array contains an equal element |
.stringContaining() | Expect helper for string substring |
.arrayContaining() | Expect helper for array subset |
Objects
| Matcher | Description |
|---|---|
.toMatchObject() | Object matches a subset of properties |
.toHaveProperty() | Object has a specific property path |
.objectContaining() | Expect helper for object subset |
Numbers
| Matcher | Description |
|---|---|
.toBeGreaterThan() | Greater than a value |
.toBeGreaterThanOrEqual() | Greater than or equal to a value |
.toBeLessThan() | Less than a value |
.toBeLessThanOrEqual() | Less than or equal to a value |
.toBeCloseTo() | Approximately equal (floating pt) |
Functions and errors
| Matcher | Description |
|---|---|
.toThrow() | Function throws an error |
.toBeInstanceOf() | Value is an instance of a class |
.resolves | Promise resolves to a value |
.rejects | Promise rejects with an error |
Mock functions
| Matcher | Description |
|---|---|
.toHaveBeenCalled() | Mock was called at least once |
.toHaveBeenCalledTimes(n) | Mock was called exactly n times |
.toHaveBeenCalledWith(...) | Mock was called with specific arguments |
.toHaveReturned() | Mock returned without throwing |
.toHaveReturnedWith(value) | Mock returned a specific value |
Snapshots
| Matcher | Description |
|---|---|
.toMatchSnapshot() | Matches a stored snapshot |
.toMatchInlineSnapshot() | Matches an inline snapshot |
.toThrowErrorMatchingSnapshot() | Error message matches snapshot |
.toThrowErrorMatchingInlineSnapshot() | Error message matches inline snap |
Best practices
Use descriptive test names
Use descriptive test names
Group related tests with describe
Group related tests with describe
Use specific matchers
Use specific matchers
Test error conditions
Test error conditions