You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
-1Lines changed: 0 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,7 +41,6 @@ Next generation testing framework powered by Vite.
41
41
-[JSDOM](https://github.com/jsdom/jsdom) and [happy-dom](https://github.com/capricorn86/happy-dom) for DOM and browser API mocking
42
42
-[Browser Mode](https://vitest.dev/guide/browser/) for running component tests in the browser
- Workers multi-threading via [Tinypool](https://github.com/tinylibs/tinypool) (a lightweight fork of [Piscina](https://github.com/piscinajs/piscina))
45
44
- Benchmarking support with [Tinybench](https://github.com/tinylibs/tinybench)
46
45
-[Projects](https://vitest.dev/guide/projects) support
47
46
-[expect-type](https://github.com/mmkal/expect-type) for type-level testing
<ListItem>Workers multi-threading via <atarget="_blank"href="https://github.com/tinylibs/tinypool"rel="noopener noreferrer">Tinypool</a></ListItem>
14
13
<ListItem>Benchmarking support with <atarget="_blank"href="https://github.com/tinylibs/tinybench"rel="noopener noreferrer">Tinybench</a></ListItem>
15
14
<ListItem>Filtering, timeouts, concurrent for suite and tests</ListItem>
This is an advanced and very low-level API. If you just want to [run tests](/guide/), you probably don't need this. It is primarily used by library authors.
4
+
This is an advanced, experimental and very low-level API. If you just want to [run tests](/guide/), you probably don't need this. It is primarily used by library authors.
5
5
:::
6
6
7
-
Vitest runs tests in pools. By default, there are several pools:
7
+
Vitest runs tests in a pool. By default, there are several pool runners:
8
8
9
9
-`threads` to run tests using `node:worker_threads` (isolation is provided with a new worker context)
10
10
-`forks` to run tests using `node:child_process` (isolation is provided with a new `child_process.fork` process)
11
11
-`vmThreads` to run tests using `node:worker_threads` (but isolation is provided with `vm` module instead of a new worker context)
12
12
-`browser` to run tests using browser providers
13
13
-`typescript` to run typechecking on tests
14
14
15
-
You can provide your own pool by specifying a file path:
15
+
::: tip
16
+
See [`vitest-pool-example`](https://www.npmjs.com/package/vitest-pool-example) for example of a custom pool runner implementation.
17
+
:::
18
+
19
+
## Usage
20
+
21
+
You can provide your own pool runner by a function that returns `PoolRunnerInitializer`.
16
22
17
23
```ts [vitest.config.ts]
18
24
import { defineConfig } from'vitest/config'
25
+
importcustomPoolfrom'./my-custom-pool.ts'
19
26
20
27
exportdefaultdefineConfig({
21
28
test: {
22
29
// will run every file with a custom pool by default
23
-
pool: './my-custom-pool.ts',
24
-
// you can provide options using `poolOptions` object
25
-
poolOptions: {
26
-
myCustomPool: {
27
-
customProperty: true,
28
-
},
29
-
},
30
+
pool: customPool({
31
+
customProperty: true,
32
+
})
30
33
},
31
34
})
32
35
```
33
36
34
37
If you need to run tests in different pools, use the [`projects`](/guide/projects) feature:
The file specified in `pool` option should export a function (can be async) that accepts `Vitest` interface as its first option. This function needs to return an object matching `ProcessPool` interface:
66
+
The `pool` option accepts a `PoolRunnerInitializer` that can be used for custom pool runners. The `name` property should indicate name of the custom pool runner. It should be identical with your worker's `name` property.
The function is called only once (unless the server config was updated), and it's generally a good idea to initialize everything you need for tests inside that function and reuse it when `runTests` is called.
79
+
In your `CustomPoolWorker` you need to define all required methods:
Vitest calls `runTest` when new tests are scheduled to run. It will not call it if `files` is empty. The first argument is an array of [TestSpecifications](/advanced/api/test-specification). Files are sorted using [`sequencer`](/config/#sequence-sequencer) before `runTests` is called. It's possible (but unlikely) to have the same file twice, but it will always have a different project - this is implemented via [`projects`](/guide/projects) configuration.
84
+
classCustomPoolWorkerimplementsPoolWorker {
85
+
name ='custom-pool'
86
+
private customOptions:CustomOptions
69
87
70
-
Vitest will wait until `runTests` is executed before finishing a run (i.e., it will emit [`onTestRunEnd`](/advanced/reporters) only after `runTests` is resolved).
If you are using a custom pool, you will have to provide test files and their results yourself - you can reference [`vitest.state`](https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/node/state.ts) for that (most important are `collectFiles` and `updateTasks`). Vitest uses `startTests` function from `@vitest/runner` package to do that.
92
+
send(message:WorkerRequest):void {
93
+
// Provide way to send your worker a message
94
+
}
73
95
74
-
Vitest will call `collectTests` if `vitest.collect` is called or `vitest list` is invoked via a CLI command. It works the same way as `runTests`, but you don't have to run test callbacks, only report their tasks by calling `vitest.state.collectFiles(files)`.
// Provide way to listen to your workers events, e.g. message, error, exit
98
+
}
75
99
76
-
To communicate between different processes, you can create methods object using `createMethodsRPC` from `vitest/node`, and use any form of communication that you prefer. For example, to use WebSockets with `birpc` you can write something like this:
function createRpc(project:TestProject, wss:WebSocketServer) {
84
-
returncreateBirpc(
85
-
createMethodsRPC(project),
86
-
{
87
-
post: msg=>wss.send(msg),
88
-
on: fn=>wss.on('message', fn),
89
-
serialize: stringify,
90
-
deserialize: parse,
91
-
},
92
-
)
108
+
async stop() {
109
+
// cleanup the state
110
+
}
111
+
112
+
deserialize(data) {
113
+
returndata
114
+
}
93
115
}
94
116
```
95
117
96
-
You can see a simple example of a pool made from scratch that doesn't run tests but marks them as collected in [pool/custom-pool.ts](https://github.com/vitest-dev/vitest/blob/main/test/cli/fixtures/custom-pool/pool/custom-pool.ts).
118
+
Your `CustomPoolRunner` will be controlling how your custom test runner worker life cycles and communication channel works. For example, your `CustomPoolRunner` could launch a `node:worker_threads``Worker`, and provide communication via `Worker.postMessage` and `parentPort`.
119
+
120
+
In your worker file, you can import helper utilities from `vitest/worker`:
121
+
122
+
```ts [my-worker.ts]
123
+
import { init, runBaseTests } from'vitest/worker'
124
+
125
+
init({
126
+
post: (response) => {
127
+
// Provide way to send this message to CustomPoolRunner's onWorker as message event
128
+
},
129
+
on: (callback) => {
130
+
// Provide a way to listen CustomPoolRunner's "postMessage" calls
131
+
},
132
+
off: (callback) => {
133
+
// Optional, provide a way to remove listeners added by "on" calls
134
+
},
135
+
teardown: () => {
136
+
// Optional, provide a way to teardown worker, e.g. unsubscribe all the `on` listeners
137
+
},
138
+
serialize: (value) => {
139
+
// Optional, provide custom serializer for `post` calls
140
+
},
141
+
deserialize: (value) => {
142
+
// Optional, provide custom deserializer for `on` callbacks
0 commit comments