Mark a test as a "todo" with the Bun test runner

To remind yourself to write a test later, use the test.todo function. An implementation isn't required.

test.test.ts
import { test } from "bun:test";

// write this later
test.todo("parses durations like 1h30m");

The bun test output reports the number of todo tests.

terminal
bun test
test.test.ts:
✎ parses durations like 1h30m

 0 pass
 1 todo
 0 fail
Ran 1 test across 1 file. [6.00ms]

You can also write the test before the code it tests exists. Here parseDuration is still a stub, and the todo test records what it should eventually do. bun test reports this test as todo too, without running its body.

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

// Not written yet; the todo test below says what it should do.
function parseDuration(input: string): number {
  throw new Error("not implemented");
}

test.todo("parses durations like 1h30m", () => {
  expect(parseDuration("1h30m")).toBe(5400);
});

Pass --todo to run the bodies of todo tests. A todo test is expected to fail: while parseDuration is unimplemented, Bun prints the error, still counts the test as todo, and exits with code 0.

terminal
bun test --todo
test.test.ts:
1 | import { test, expect } from "bun:test";
2 |
3 | // Not written yet; the todo test below says what it should do.
4 | function parseDuration(input: string): number {
5 |   throw new Error("not implemented");
                                       ^
error: not implemented
      at parseDuration (/path/to/test.test.ts:5:36)
      at <anonymous> (/path/to/test.test.ts:9:10)
✎ parses durations like 1h30m [0.16ms]

 0 pass
 1 todo
 0 fail
Ran 1 test across 1 file. [5.00ms]

Once you implement parseDuration and the body passes, bun test --todo reports the test as a failure and exits with a non-zero code. That is the signal to remove .todo and turn it into a regular test.

test.test.ts:
✗ parses durations like 1h30m [0.19ms]
  ^ this test is marked as todo but passes. Remove `.todo` if tested behavior now works

 0 pass
 1 fail
 1 expect() calls
Ran 1 test across 1 file. [5.00ms]
$ echo $?
1 # this is the exit code of the previous command

See also: