diff options
Diffstat (limited to 'docs/test')
-rw-r--r-- | docs/test/extending.md | 162 | ||||
-rw-r--r-- | docs/test/lifecycle.md | 81 | ||||
-rw-r--r-- | docs/test/snapshots.md | 15 | ||||
-rw-r--r-- | docs/test/writing.md | 48 |
4 files changed, 113 insertions, 193 deletions
diff --git a/docs/test/extending.md b/docs/test/extending.md deleted file mode 100644 index 385957693..000000000 --- a/docs/test/extending.md +++ /dev/null @@ -1,162 +0,0 @@ -Like the runtime, `bun:test` also supports `--preload` scripts. These scripts are loaded before any tests are run. This is useful for setting up test fixtures, mocking, and configuring the test environment. - -{% codetabs %} - -```ts#preloaded.ts -import { beforeAll, beforeEach, afterEach, afterAll } from "bun:test"; - -beforeAll(() => { - console.log("beforeAll"); -}); - -beforeEach(() => { - console.log("beforeEach"); -}); - -afterEach(() => { - console.log("afterEach"); -}); - -afterAll(() => { - console.log("afterAll"); -}); -``` - -{% /codetabs %} - -Test file: - -```ts -import { expect, test } from "bun:test"; - -test("1 + 1", () => { - expect(1 + 1).toEqual(2); - console.log("1 + 1"); -}); -``` - -Run the test with `--preload`: - -```sh -$ bun test --preload=preloaded.ts -``` - -It outputs: - -```sh -beforeAll -beforeEach -1 + 1 -afterEach -afterAll -``` - -## Configuration - -To save yourself from having to type `--preload` every time you run tests, you can add it to your `bunfig.toml`: - -```toml -[test] -preload = ["./preloaded.ts"] -``` - -## List of lifecycle hooks - -The following lifecycle hooks are available in `--preload`: - -| Hook | Description | -| ------------ | --------------------------- | -| `beforeAll` | Runs once before all tests. | -| `beforeEach` | Runs before each test. | -| `afterEach` | Runs after each test. | -| `afterAll` | Runs once after all tests. | - -Calling `expect`, `test`, or any other test function inside a lifecycle hook will throw an error. Calling `test` inside `beforeAll`, `afterAll`, `beforeEach` or `afterEach` will also throw an error. - -You can use `console.log` or any other function otherwise inside a lifecycle hook. - -We haven't implemented timer simulation, test isolation, or `Math.random` mocking yet. If you need these features, please [open an issue](https://bun.sh/issues). - -### The lifecycle of bun:test - -The test runner is a single process that runs all tests. It loads all `--preload` scripts, then runs all tests. If a test fails, the test runner will exit with a non-zero exit code. - -Before running each test, it transpiles the source code and all dependencies into vanilla JavaScript using Bun's transpiler and module resolver. This means you can use TypeScript, JSX, ESM, and CommonJS in your tests. - -#### Globals - -Like Jest, you can use `describe`, `test`, `expect`, and other functions without importing them. - -But unlike Jest, they are not globals. They are imported from `bun:test` and are exclusively available in test files or when preloading scripts. - -```ts -typeof globalThis.describe; // "undefined" -typeof describe; // "function" -``` - -This works via a transpiler integration in Bun. When `describe`, `expect`, `it`, etc are used in a test file, the transpiler auto-imports from `bun:test`. This transpiler plugin is only enabled inside test files and when preloading scripts. If you try to use Jest globals in other files, you will get an error. - -Every `describe`, `test`, and `expect` is scoped to the current test file. Importing from `"bun:test"` creates a new scope. This means you can't use `describe` from one test file in another test file because belong to different scopes. - -## Loaders & Resolvers - -{% note %} -Plugin support is not implemented yet. **There is a bug and this feature is not working**. -{% /note %} - -`bun:test` supports the same plugin API as bun's runtime and bun's bundler. See [Plugins](/docs/bundler/plugins#usage) for more information. - -## Example loader - -{% codetabs %} - -```ts#loader.ts -import { plugin } from 'bun'; - -plugin({ - name: 'My loader', - setup(build) { - build.onResolve({ filter: /\.txt$/ }, (args) => { - return { - path: args.path, - namespace: 'my-loader', - }; - }); - - build.onLoad({ filter: /my-loader:.txt$/ }, (args) => { - return { - contents: 'Hello world!', - loader: 'text', - }; - }); - }, -}); -``` - -{% /codetabs %} - -Now in your test file, you can import `.txt` files: - -```ts#my-test.test.ts -import { expect, test } from "bun:test"; -import text from "./hello.txt"; - -test("text is 'Hello world!'", () => { - expect(text).toEqual("Hello world!"); -}); -``` - -To run the test, you need to add `loader.ts` to `preload`: - -```toml -[test] -preload = ["loader.ts"] -``` - -Or you can pass --preload to the command line: - -```sh -$ bun test --preload=loader.ts -``` - -TODO: `expect.extend` diff --git a/docs/test/lifecycle.md b/docs/test/lifecycle.md new file mode 100644 index 000000000..ccb7ce85d --- /dev/null +++ b/docs/test/lifecycle.md @@ -0,0 +1,81 @@ +The test runner supports the following lifecycle hooks. This is useful for loading test fixtures, mocking data, and configuring the test environment. + +| Hook | Description | +| ------------ | --------------------------- | +| `beforeAll` | Runs once before all tests. | +| `beforeEach` | Runs before each test. | +| `afterEach` | Runs after each test. | +| `afterAll` | Runs once after all tests. | + +Perform per-test setup and teardown logic with `beforeEach` and `afterEach`. + +```ts +import { expect, test } from "bun:test"; + +beforeEach(() => { + console.log("running test."); +}); + +afterEach(() => { + console.log("done with test."); +}); + +// tests... +``` + +Perform per-scope setup and teardown logic with `beforeAll` and `afterAll`. The _scope_ is determined by where the hook is defined. + +To scope the hooks to a particular `describe` block: + +```ts +import { describe, beforeAll } from "bun:test"; + +describe("test group", () => { + beforeAll(() => { + // setup + }); + + // tests... +}); +``` + +To scope the hooks to a test file: + +```ts +import { describe, beforeAll } from "bun:test"; + +describe("test group", () => { + beforeAll(() => { + // setup + }); + + // tests... +}); +``` + +To scope the hooks to an entire multi-file test run, define the hooks in a separate file. + +```ts#setup.ts +import { beforeAll, afterAll } from "bun:test"; + +beforeAll(() => { + // global setup +}); + +afterAll(() => { + // global teardown +}); +``` + +Then use `--preload` to run the setup script before any test files. + +```ts +bun test --preload ./setup.ts +``` + +To avoid typing `--preload` every time you run tests, it can be added to your `bunfig.toml`: + +```toml +[test] +preload = ["./setup.ts"] +``` diff --git a/docs/test/snapshots.md b/docs/test/snapshots.md new file mode 100644 index 000000000..46df217ce --- /dev/null +++ b/docs/test/snapshots.md @@ -0,0 +1,15 @@ +Snapshot tests are written using the `.toMatchSnapshot()` matcher: + +```ts +import { test, expect } from "bun:test"; + +test("snap", () => { + expect("foo").toMatchSnapshot(); +}); +``` + +The first time this test is run, the argument to `expect` will be serialized and written to a special snapshot file in a `__snapshots__` directory alongside the test file. On future runs, the argument is compared against the snapshot on disk. Snapshots can be re-generated with the following command: + +```bash +$ bun test --update-snapshots +``` diff --git a/docs/test/writing.md b/docs/test/writing.md index b79f88a0f..46773c1d2 100644 --- a/docs/test/writing.md +++ b/docs/test/writing.md @@ -12,6 +12,17 @@ test("2 + 2", () => { }); ``` +{% details summary="Jest-style globals" %} +As in Jest, you can use `describe`, `test`, `expect`, and other functions without importing them. Unlike Jest, they are not injected into the global scope. Instead, the Bun transpiler will automatically inject an import from `bun:test` internally. + +```ts +typeof globalThis.describe; // "undefined" +typeof describe; // "function" +``` + +This transpiler integration only occurs during `bun test`, and only for test files & preloaded scripts. In practice there's no significant difference to the end user. +{% /details %} + Tests can be grouped into suites with `describe`. ```ts#math.test.ts @@ -52,7 +63,7 @@ test("2 * 2", done => { }); ``` -Skip individual tests with `test.skip`. +Skip individual tests with `test.skip`. These tests will not be run. ```ts import { expect, test } from "bun:test"; @@ -63,41 +74,14 @@ test.skip("wat", () => { }); ``` -## Setup and teardown - -Perform per-test setup and teardown logic with `beforeEach` and `afterEach`. +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. ```ts import { expect, test } from "bun:test"; -beforeEach(() => { - console.log("running test."); -}); - -afterEach(() => { - console.log("done with test."); -}); - -// tests... -``` - -Perform per-scope setup and teardown logic with `beforeAll` and `afterAll`. At the top-level, the _scope_ is the current file; in a `describe` block, the scope is the block itself. - -```ts -import { expect, test, beforeAll, afterAll } from "bun:test"; - -let db: Database; -beforeAll(() => { - // connect to database - db = initializeDatabase(); +test.todo("fix this", () => { + myTestFunction(); }); - -afterAll(() => { - // close connection - db.close(); -}); - -// tests... ``` ## Matchers @@ -106,6 +90,8 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap {% table %} +--- + - 🟢 - [`.not`](https://jestjs.io/docs/expect#not) |