Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Workers] Add docs for Vitest testing #13092

Merged
merged 58 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
9f6ad69
workers: initial testing docs commit. add files for structure per ToC.
admah Jan 31, 2024
5481020
add page write your first test
admah Feb 13, 2024
b9f904a
add config and setup sections to first test doc.
admah Feb 20, 2024
cf0b012
add sample tests to first test guide. add first sentence to unstable …
admah Feb 20, 2024
2add72b
update docs to reference vitest 1.3.0. add section for configuring vi…
admah Feb 20, 2024
7250135
Reorder table-of-contents
mrbbot Feb 20, 2024
a266e51
Add migration from Miniflare 2's testing environments page
mrbbot Feb 20, 2024
4a3494b
Add testing options page
mrbbot Feb 20, 2024
19364fd
Add configuration page
mrbbot Feb 20, 2024
e39f3d6
Add test APIs page
mrbbot Feb 20, 2024
5947811
Add internal details page
mrbbot Feb 20, 2024
cade5b2
add migration docs for unstable_dev
admah Feb 20, 2024
a68d2ea
remove testing section from local dev guide
admah Feb 20, 2024
fe0d63f
add callouts for additional config info docs
admah Feb 20, 2024
2456419
add recipes for fetch events and scheduled events.
admah Feb 21, 2024
7b7a8c8
add advanced config and integration test examples.
admah Feb 21, 2024
7a2994c
Minor fixups to `migrate-from-miniflare-2.md` and `configuration.md`
mrbbot Feb 22, 2024
6418117
Update content/workers/testing/vitest/get-started/migrate-from-unstab…
admah Feb 22, 2024
3ba6545
Update content/workers/testing/vitest/get-started/migrate-from-unstab…
admah Feb 22, 2024
52035e4
Update content/workers/testing/vitest/get-started/write-your-first-te…
admah Feb 22, 2024
a776599
Update content/workers/testing/vitest/get-started/write-your-first-te…
admah Feb 22, 2024
5f18637
update unstable_dev migration guide per comments. update first test e…
admah Feb 23, 2024
e154e1b
add npm command to install vitest 1.3.0
admah Feb 23, 2024
b531643
move vitest into section about installing packages. add note about on…
admah Feb 23, 2024
70af281
Update content/workers/testing/vitest/get-started/write-your-first-te…
admah Feb 23, 2024
21ec0b4
Update content/workers/testing/vitest/get-started/write-your-first-te…
admah Feb 23, 2024
dd3d3aa
Add isolation model diagrams to internal details page
mrbbot Feb 27, 2024
96362d0
More minor fixups to `configuration.md`
mrbbot Feb 27, 2024
e4226b5
remove recipe examples. add links to fixtures folder.
admah Feb 27, 2024
6e48e51
add compat date and flag to prereqs
admah Mar 1, 2024
0e73ff6
Replace `Vitest pool` with `Vitest integration`
mrbbot Mar 4, 2024
8942b8c
Update `configuration.md` in response to review
mrbbot Mar 4, 2024
885b75f
Update `migrate-from-miniflare-2.md` in response to review
mrbbot Mar 4, 2024
3c9915e
Update `internal-details.md` in response to review
mrbbot Mar 4, 2024
7b675f7
Update `test-apis.md` in response to review
mrbbot Mar 4, 2024
183639b
fixup! Update `configuration.md` in response to review
mrbbot Mar 4, 2024
6214c0a
update testing section structure. add pages for unit and integration …
admah Mar 4, 2024
be383d7
update testing section description
admah Mar 4, 2024
20e3a5f
add description for vitest integration
admah Mar 4, 2024
ecee377
add vitest integration description
admah Mar 4, 2024
1966150
update docs to reflect api changes for defineWorkersConfig
admah Mar 6, 2024
55002cf
add more info about SELF and auxiliary Workers
admah Mar 10, 2024
aa0e03d
Apply suggestions from code review
deadlypants1973 Mar 11, 2024
d6715fc
PCX review test
deadlypants1973 Mar 12, 2024
8a397b8
Apply suggestions from code review
deadlypants1973 Mar 12, 2024
059671b
Apply suggestions from code review
deadlypants1973 Mar 12, 2024
9b4bd20
PCX review for write your first test and isolation
deadlypants1973 Mar 12, 2024
81751a1
Apply suggestions from code review
admah Mar 12, 2024
39e1841
update api code blocks. add recipe links.
admah Mar 13, 2024
95fd9c3
add partial to reference pages functions. add partial to relevant pages.
admah Mar 13, 2024
2c17dab
add auxiliary worker glossary term. update integration testing page.
admah Mar 13, 2024
9ddf5d2
Merge branch 'production' into admah/vitest-pool-docs
mrbbot Mar 13, 2024
698b2b1
Apply more suggestions from code review
mrbbot Mar 13, 2024
2dd232f
Minor fixups
mrbbot Mar 13, 2024
0821fda
Add known issues
mrbbot Mar 13, 2024
69e7614
edit first test examples to match c3
admah Mar 13, 2024
04c4d34
Fix broken links
mrbbot Mar 13, 2024
7aae21d
Replace `we` with `Cloudflare` per style guide
mrbbot Mar 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/CodeCopy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ function copyCode(e: MouseEvent) {
width: 2rem;
font-size: 0.9rem;
padding: 0.5rem;
box-sizing: border-box;
mrbbot marked this conversation as resolved.
Show resolved Hide resolved
background: #d9d9d9;
color: #1e1e1e;
border: none;
Expand Down
4 changes: 2 additions & 2 deletions content/workers/observability/_index.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
pcx_content_type: navigation
title: Observability
weight: 9
weight: 10
---

# Observability

Test and debug your Worker projects.
Understand how your Worker projects are performing via logs, traces, and other data sources.

{{<directory-listing showDescriptions="true">}}
11 changes: 11 additions & 0 deletions content/workers/testing/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
pcx_content_type: navigation
title: Testing
weight: 9
---

# Testing

Test and debug your Worker projects.
mrbbot marked this conversation as resolved.
Show resolved Hide resolved

{{<directory-listing showDescriptions="true">}}
mrbbot marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
---
title: Local development and testing
title: Local development
weight: 2
pcx_content_type: concept
meta:
description: Test your Worker in local development.
---

# Local development and testing
# Local development

Cloudflare Workers can be fully developed and tested locally - providing confidence that the applications you develop locally work the same way in production. This allows you to be more efficient and effective by providing a faster feedback loop and removing the need to test against remote resources. Local development runs against the same production runtime used by Cloudflare Workers, [workerd](https://github.com/cloudflare/workerd).

Expand Down Expand Up @@ -117,20 +118,6 @@ The `.vscode/launch.json` file only applies to a single workspace. If you prefer

{{</Aside>}}

## Test Workers

### Integration testing

Wrangler offers an experimental API, `unstable_dev`, that will allow you to start a server for integration testing.

For more information and examples, refer to the [`unstable_dev` guide](/workers/wrangler/api/#unstable_dev).

### Advanced local testing via Miniflare

[Miniflare](https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare#readme) is a simulator for developing and testing Workers. It supports simulating and mocking resources like: KV, Durable Objects, R2, D1, and Queues.

Miniflare is fully local, and is built on top of the Workers runtime, [`workerd`](https://github.com/cloudflare/workerd) to ensure that local behavior accurately reflects production. All of this makes it a great tool for writing tests or advanced use cases.

## Related resources

* [Log from Workers](/workers/observability/logging/real-time-logs) - Access logs and exceptions for your Workers using the dashboard or [`wrangler tail`](/workers/wrangler/commands/#tail).
154 changes: 154 additions & 0 deletions content/workers/testing/testing-options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
title: Testing options
pcx_content_type: overview
weight: 3
---

# Testing options

There are many ways of testing Workers and Pages projects. This page gives an overview of the different types of tests and which methods are most appropriate for each.
mrbbot marked this conversation as resolved.
Show resolved Hide resolved

## Types of tests

In a Workers context, a unit test imports and directly calls functions from your Worker then asserts on their return values. By contrast, an integration test sends HTTP requests to your Worker and asserts on the HTTP responses. For an illustrative example, consider the following Worker:

```js
---
filename: index.mjs
---
export function add(a, b) {
return a + b;
}

export default {
async fetch(request) {
const url = new URL(request.url);
const a = parseInt(url.searchParams.get("a"));
const b = parseInt(url.searchParams.get("b"));
return new Response(add(a, b));
}
}
```

A unit test might look like...

```js
import { add } from "./index.mjs";
assert(add(1, 2) === 3);
```

...whereas an integration test might look like...

```js
// Start Worker HTTP server on port 8787 running `index.mjs` then...
const response = await fetch("http://localhost:8787/?a=1&b=2");
assert((await response.text()) === "3");
```

Note whilst we're not limited to the HTTP abstraction with unit tests, we could call the `fetch` handler directly for an _integration-like_ unit test. Unit tests may be considered more expressive than integration tests, but integration tests usually provide a more accurate environment.

```js
import worker from "./my-worker.mjs";
const request = new Request("http://example.com/?a=1&b=2");
const response = await worker.fetch(request);
assert((await response.text()) === "3");
```

## Vitest with Workers pool

For most users, Cloudflare recommends using our [custom Vitest pool](/workers/testing/vitest/get-started/) for testing Workers and [Pages Functions](/pages/functions/) projects. [Vitest](https://vitest.dev/) is a popular JavaScript testing framework featuring a very fast watch mode, Jest compatibility, and out-of-the-box support for TypeScript. Cloudflare provides a custom pool that allows your Vitest tests to run _inside_ the Workers runtime. Get started with the pool [here](/workers/testing/vitest/get-started/), and check out the [recipes for testing different types of Workers](/workers/testing/vitest/recipes/).
mrbbot marked this conversation as resolved.
Show resolved Hide resolved

- ✅ Supports both **unit tests** and **integration tests**
- 📚 Provides direct access to Workers runtime APIs and bindings
- 📦 Implements isolated per-test storage
- 🔥 Runs tests fully-locally using [Miniflare](https://miniflare.dev/)
- ⚡️ Leverages Vitest's hot-module reloading for near instant reruns
- ↩️ Provides a declarative interface for mocking outbound requests
- 🧩 Supports projects with multiple workers

{{<Aside type="warning">}}

The Workers Vitest pool does not support testing Workers using the Service Worker format. Please [migrate to the ES modules format](/workers/reference/migrate-to-module-workers/) first.

{{</Aside>}}

```js
import {
env,
SELF,
createExecutionContext,
waitOnExecutionContext,
} from "cloudflare:test";
import { it, expect } from "vitest";
import worker, { add } from "./index.mjs";

it("adds via function call", () => {
expect(add(1, 2)).toBe(3);
});
it("adds via request (unit style)", () => {
const request = new Request("http://example.com/?a=1&b=2");
const ctx = createExecutionContext();
const response = await worker.fetch(request, env, ctx);
await waitOnExecutionContext(ctx);
expect(await response.text()).toBe("3");
});
it("adds via request (integration style)", () => {
const response = await SELF.fetch("http://example.com/?a=1&b=2");
expect(await response.text()).toBe("3");
});
```

## Wrangler's `unstable_dev()` API

If you do not want to use Vitest and would like to write **integration tests** for a single worker, consider using [Wrangler's `unstable_dev()` API](/workers/wrangler/api/#unstable_dev). This allows you to start an HTTP server similar to `wrangler dev` that you can send HTTP requests to. `unstable_dev()` will automatically load options from your Wrangler configuration file. Note this is an experimental API subject to breaking changes.

```js
import assert from "node:assert";
import { unstable_dev } from "wrangler";

const worker = await unstable_dev("./index.mjs");
try {
const response = await worker.fetch("/?a=1&b=2");
assert.strictEqual(await response.text(), "3");
} finally {
await worker.stop();
}
```

## Miniflare's API

If you would like to write **integration tests** for multiple workers, need direct access to bindings outside your worker in tests, or have another advanced use case, consider using [Miniflare's API](https://github.com/cloudflare/workers-sdk/blob/main/packages/miniflare/README.md) directly. Miniflare is the foundation for the other solutions on this page, exposing a JavaScript API for the [`workerd` runtime](https://github.com/cloudflare/workerd) and local simulators for the other Developer Platform products. Unlike `unstable_dev()`, Miniflare does not automatically load options from your Wrangler configuration file.

```js
import assert from "node:assert";
import { Miniflare } from "miniflare";

const mf = new Miniflare({
modules: true,
scriptPath: "./index.mjs",
});
try {
const response = await mf.dispatchFetch("http://example.com/?a=1&b=2");
assert.strictEqual(await response.text(), "3");
} finally {
await mf.dispose();
}
```

## Comparison matrix

| Feature | Vitest&nbsp;Pool | `unstable_dev()` | Miniflare's&nbsp;API |
| ----------------------------------------- | ---------------- | ---------------- | -------------------- |
| Unit testing | ✅ | ❌ | ❌ |
| Integration testing | ✅ | ✅ | ✅ |
| Loading Wrangler configuration files | ✅ | ✅ | ❌ |
| Bindings directly in tests | ✅ | ❌ | ✅ |
| Isolated per-test storage | ✅ | ❌ | ❌ |
| Outbound request mocking | ✅ | ❌ | ✅ |
| Multiple Workers support | ✅ | 🚧[^1] | ✅ |
| Direct access to Durable Object instances | ✅ | ❌ | ❌ |
| Run Durable Object alarms immediately | ✅ | ❌ | ❌ |
| List Durable Objects | ✅ | ❌ | ❌ |
| Testing Service Workers | ❌ | ✅ | ✅ |

[^1]: Support for multiple workers in `unstable_dev()` relies on `wrangler dev`'s service registry which can be unreliable when running multiple tests in parallel.
11 changes: 11 additions & 0 deletions content/workers/testing/vitest/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
pcx_content_type: navigation
title: Vitest
weight: 4
---

# Vitest

Test and debug your Worker projects via Vitest.

{{<directory-listing showDescriptions="true">}}
Loading
Loading