Bun

Writing tests

Define tests with a Jest-like API imported from the built-in 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 simple test:

math.test.ts
import { expect, test } from "bun:test";

test("2 + 2", () => {
  expect(2 + 2).toBe(4);
});

Jest-style globals

Tests can be grouped into suites with describe.

math.test.ts
import { expect, test, describe } from "bun:test";

describe("arithmetic", () => {
  test("2 + 2", () => {
    expect(2 + 2).toBe(4);
  });

  test("2 * 2", () => {
    expect(2 * 2).toBe(4);
  });
});

Tests can be async.

import { expect, test } from "bun:test";

test("2 * 2", async () => {
  const result = await Promise.resolve(2 * 2);
  expect(result).toEqual(4);
});

Alternatively, use the 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.

import { expect, test } from "bun:test";

test("2 * 2", done => {
  Promise.resolve(2 * 2).then(result => {
    expect(result).toEqual(4);
    done();
  });
});

Timeouts

Optionally specify a per-test timeout in milliseconds by passing a number as the third argument to test.

import { test } from "bun:test";

test("wat", async () => {
  const data = await slowOperation();
  expect(data).toBe(42);
}, 500); // test must run in <500ms

test.skip

Skip individual tests with test.skip. These tests will not be run.

import { expect, test } from "bun:test";

test.skip("wat", () => {
  // TODO: fix this
  expect(0.1 + 0.2).toEqual(0.3);
});

test.todo

Mark a test as a todo with test.todo. These tests will be run, and the test runner will expect them to fail. If they pass, you will be prompted to mark it as a regular test.

import { expect, test } from "bun:test";

test.todo("fix this", () => {
  myTestFunction();
});

To exclusively run tests marked as todo, use bun test --todo.

bun test --todo

test.only

To run a particular test or suite of tests use test.only() or describe.only(). Once declared, running bun test --only will only execute tests/suites that have been marked with .only().

import { test, describe } from "bun:test";

test("test #1", () => {
  // does not run
});

test.only("test #2", () => {
  // runs
});

describe.only("only", () => {
  test("test #3", () => {
    // runs
  });
});

The following command will only execute tests #2 and #3.

bun test --only

test.if

To run a test conditionally, use test.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.

test.if(Math.random() > 0.5)("runs half the time", () => {
  // ...
});

const macOS = process.arch === "darwin";
test.if(macOS)("runs on macOS", () => {
  // runs if macOS
});

To instead skip a test based on some condition, use test.skipIf() or describe.skipIf().

const macOS = process.arch === "darwin";

test.skipIf(macOS)("runs on non-macOS", () => {
  // runs if *not* macOS
});

Matchers

Bun implements the following matchers. Full Jest compatibility is on the roadmap; track progress here.