bun:test module. Long term, Bun aims for complete Jest compatibility; at the moment, a limited set of expect matchers are supported.
Basic Usage
To define a test:math.test.ts
Grouping Tests
Tests can be grouped into suites withdescribe.
math.test.ts
Async Tests
Tests can be async.math.test.ts
done callback to signal completion. If you include the done callback as a parameter in your test definition, you must call it or the test will hang.
math.test.ts
Timeouts
Optionally specify a per-test timeout in milliseconds by passing a number as the third argument totest.
math.test.ts
bun:test, test timeouts throw an uncatchable exception to force the test to stop running and fail. We also kill any child processes that were spawned in the test to avoid leaving behind zombie processes lurking in the background.
The default timeout for each test is 5000ms (5 seconds) if not overridden by this timeout option or jest.setDefaultTimeout().
Retries and Repeats
test.retry
Use theretry option to automatically retry a test if it fails. The test passes if it succeeds within the specified number of attempts. This is useful for flaky tests that may fail intermittently.
example.test.ts
test.repeats
Use therepeats option to run a test multiple times regardless of pass/fail status. The test fails if any iteration fails. This is useful for detecting flaky tests or stress testing. Note that repeats: N runs the test N+1 times total (1 initial run + N repeats).
example.test.ts
You cannot use both
retry and repeats on the same test.🧟 Zombie Process Killer
When a test times out and processes spawned in the test viaBun.spawn, Bun.spawnSync, or node:child_process are not killed, they will be automatically killed and a message will be logged to the console. This prevents zombie processes from lingering in the background after timed-out tests.
Test Modifiers
test.skip
Skip individual tests withtest.skip. These tests will not be run.
math.test.ts
test.todo
Mark a test as a todo withtest.todo. These tests will not be run.
math.test.ts
bun test --todo.
terminal
test.only
To run a particular test or suite of tests usetest.only() or describe.only().
example.test.ts
terminal
terminal
test.if
To run a test conditionally, usetest.if(). The test will run if the condition is truthy. This is particularly useful for tests that should only run on specific architectures or operating systems.
example.test.ts
test.skipIf
To instead skip a test based on some condition, usetest.skipIf() or describe.skipIf().
example.test.ts
test.todoIf
If instead you want to mark the test as TODO, usetest.todoIf() or describe.todoIf(). Carefully choosing skipIf or todoIf can show a difference between, for example, intent of “invalid for this target” and “planned but not implemented yet.”
example.test.ts
test.failing
Usetest.failing() when you know a test is currently failing but you want to track it and be notified when it starts passing. This inverts the test result:
- A failing test marked with
.failing()will pass - A passing test marked with
.failing()will fail (with a message indicating it’s now passing and should be fixed)
math.test.ts
Conditional Tests for Describe Blocks
The conditional modifiers.if(), .skipIf(), and .todoIf() can also be applied to describe blocks, affecting all tests within the suite:
example.test.ts
Parametrized Tests
test.each and describe.each
To run the same test with multiple sets of data, use test.each. This creates a parametrized test that runs once for each test case provided.
math.test.ts
describe.each to create a parametrized suite that runs once for each test case:
sum.test.ts
Argument Passing
How arguments are passed to your test function depends on the structure of your test cases:- If a table row is an array (like
[1, 2, 3]), each element is passed as an individual argument - If a row is not an array (like an object), it’s passed as a single argument
example.test.ts
Format Specifiers
The following options are available for formatting the test title:Examples
example.test.ts
Assertion Counting
Bun supports verifying that a specific number of assertions were called during a test:expect.hasAssertions()
Useexpect.hasAssertions() to verify that at least one assertion is called during a test:
example.test.ts
expect.assertions(count)
Useexpect.assertions(count) to verify that a specific number of assertions are called during a test:
example.test.ts
Type Testing
Bun includesexpectTypeOf for testing TypeScript types, compatible with Vitest.
expectTypeOf
TheexpectTypeOf function provides type-level assertions that are checked by TypeScript’s type checker. To test your types:
- Write your type assertions using
expectTypeOf - Run
bunx tsc --noEmitto check that your types are correct
example.test.ts
Matchers
Bun implements the following matchers. Full Jest compatibility is on the roadmap; track progress here.Basic Matchers
String and Array Matchers
Object Matchers
Number Matchers
Function and Class Matchers
Promise Matchers
Mock Function Matchers
Snapshot Matchers
Utility Matchers
Not Yet Implemented
Best Practices
Use Descriptive Test Names
example.test.ts
Group Related Tests
auth.test.ts
Use Appropriate Matchers
auth.test.ts
Test Error Conditions
example.test.ts
Use Setup and Teardown
example.test.ts