Skip to content

Commit 3a231a7

Browse files
authored
docs: add more documentation to runner tasks (#6068)
1 parent 97d9547 commit 3a231a7

File tree

3 files changed

+307
-32
lines changed

3 files changed

+307
-32
lines changed

docs/advanced/runner.md

+138-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
This is advanced API. If you are just running tests, you probably don't need this. It is primarily used by library authors.
55
:::
66

7-
You can specify a path to your test runner with the `runner` option in your configuration file. This file should have a default export with a class implementing these methods:
7+
You can specify a path to your test runner with the `runner` option in your configuration file. This file should have a default export with a class constructor implementing these methods:
88

99
```ts
1010
export interface VitestRunner {
@@ -106,9 +106,145 @@ Vitest also injects an instance of `ViteNodeRunner` as `__vitest_executor` prope
106106
Snapshot support and some other features depend on the runner. If you don't want to lose it, you can extend your runner from `VitestTestRunner` imported from `vitest/runners`. It also exposes `BenchmarkNodeRunner`, if you want to extend benchmark functionality.
107107
:::
108108

109+
## Tasks
110+
111+
Suites and tests are called `tasks` internally. Vitest runner initiates a `File` task before collecting any tests - this is a superset of `Suite` with a few additional properties. It is available on every task (including `File`) as a `file` property.
112+
113+
```ts
114+
interface File extends Suite {
115+
/**
116+
* The name of the pool that the file belongs to.
117+
* @default 'forks'
118+
*/
119+
pool?: string
120+
/**
121+
* The path to the file in UNIX format.
122+
*/
123+
filepath: string
124+
/**
125+
* The name of the workspace project the file belongs to.
126+
*/
127+
projectName: string | undefined
128+
/**
129+
* The time it took to collect all tests in the file.
130+
* This time also includes importing all the file dependencies.
131+
*/
132+
collectDuration?: number
133+
/**
134+
* The time it took to import the setup file.
135+
*/
136+
setupDuration?: number
137+
/**
138+
* Whether the file is initiated without running any tests.
139+
* This is done to populate state on the server side by Vitest.
140+
*/
141+
local?: boolean
142+
}
143+
```
144+
145+
Every suite has a `tasks` property that is populated during collection phase. It is useful to traverse the task tree from the top down.
146+
147+
```ts
148+
interface Suite extends TaskBase {
149+
type: 'suite'
150+
/**
151+
* File task. It's the root task of the file.
152+
*/
153+
file: File
154+
/**
155+
* An array of tasks that are part of the suite.
156+
*/
157+
tasks: Task[]
158+
}
159+
```
160+
161+
Every task has a `suite` property that references a suite it is located in. If `test` or `describe` are initiated at the top level, they will not have a `suite` property (it will **not** be equal to `file`!). `File` also never has a `suite` property. It is useful to travers the tasks from the bottom up.
162+
163+
```ts
164+
interface Test<ExtraContext = object> extends TaskBase {
165+
type: 'test'
166+
/**
167+
* Test context that will be passed to the test function.
168+
*/
169+
context: TaskContext<Test> & ExtraContext & TestContext
170+
/**
171+
* File task. It's the root task of the file.
172+
*/
173+
file: File
174+
/**
175+
* Whether the task was skipped by calling `t.skip()`.
176+
*/
177+
pending?: boolean
178+
/**
179+
* Whether the task should succeed if it fails. If the task fails, it will be marked as passed.
180+
*/
181+
fails?: boolean
182+
/**
183+
* Hooks that will run if the task fails. The order depends on the `sequence.hooks` option.
184+
*/
185+
onFailed?: OnTestFailedHandler[]
186+
/**
187+
* Hooks that will run after the task finishes. The order depends on the `sequence.hooks` option.
188+
*/
189+
onFinished?: OnTestFinishedHandler[]
190+
/**
191+
* Store promises (from async expects) to wait for them before finishing the test
192+
*/
193+
promises?: Promise<any>[]
194+
}
195+
```
196+
197+
Every task can have a `result` field. Suites can only have this field if an error thrown within a suite callback or `beforeAll`/`afterAll` callbacks prevents them from collecting tests. Tests always have this field after their callbacks are called - the `state` and `errors` fields are present depending on the outcome. If an error was thrown in `beforeEach` or `afterEach` callbacks, the thrown error will be present in `task.result.errors`.
198+
199+
```ts
200+
export interface TaskResult {
201+
/**
202+
* State of the task. Inherits the `task.mode` during collection.
203+
* When the task has finished, it will be changed to `pass` or `fail`.
204+
* - **pass**: task ran successfully
205+
* - **fail**: task failed
206+
*/
207+
state: TaskState
208+
/**
209+
* Errors that occurred during the task execution. It is possible to have several errors
210+
* if `expect.soft()` failed multiple times.
211+
*/
212+
errors?: ErrorWithDiff[]
213+
/**
214+
* How long in milliseconds the task took to run.
215+
*/
216+
duration?: number
217+
/**
218+
* Time in milliseconds when the task started running.
219+
*/
220+
startTime?: number
221+
/**
222+
* Heap size in bytes after the task finished.
223+
* Only available if `logHeapUsage` option is set and `process.memoryUsage` is defined.
224+
*/
225+
heap?: number
226+
/**
227+
* State of related to this task hooks. Useful during reporting.
228+
*/
229+
hooks?: Partial<Record<'afterAll' | 'beforeAll' | 'beforeEach' | 'afterEach', TaskState>>
230+
/**
231+
* The amount of times the task was retried. The task is retried only if it
232+
* failed and `retry` option is set.
233+
*/
234+
retryCount?: number
235+
/**
236+
* The amount of times the task was repeated. The task is repeated only if
237+
* `repeats` option is set. This number also contains `retryCount`.
238+
*/
239+
repeatCount?: number
240+
}
241+
```
242+
109243
## Your Task Function
110244

111-
You can extend Vitest task system with your tasks. A task is an object that is part of a suite. It is automatically added to the current suite with a `suite.task` method:
245+
Vitest exposes a `Custom` task type that allows users to reuse built-int reporters. It is virtually the same as `Test`, but has a type of `'custom'`.
246+
247+
A task is an object that is part of a suite. It is automatically added to the current suite with a `suite.task` method:
112248

113249
```js
114250
// ./utils/custom.js
@@ -167,7 +303,3 @@ vitest ./garden/tasks.test.js
167303
::: warning
168304
If you don't have a custom runner or didn't define `runTest` method, Vitest will try to retrieve a task automatically. If you didn't add a function with `setFn`, it will fail.
169305
:::
170-
171-
::: tip
172-
Custom task system supports hooks and contexts. If you want to support property chaining (like, `only`, `skip`, and your custom ones), you can import `createChainable` from `vitest/suite` and wrap your function with it. You will need to call `custom` as `custom.call(this)`, if you decide to do this.
173-
:::

packages/runner/src/types/runner.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import type {
1212
Test,
1313
} from './tasks'
1414

15+
/**
16+
* This is a subset of Vitest config that's required for the runner to work.
17+
*/
1518
export interface VitestRunnerConfig {
1619
root: string
1720
setupFiles: string[]
@@ -83,7 +86,7 @@ export interface VitestRunner {
8386
/**
8487
* When the task has finished running, but before cleanup hooks are called
8588
*/
86-
onTaskFinished?: (test: Task) => unknown
89+
onTaskFinished?: (test: Test | Custom) => unknown
8790
/**
8891
* Called after result and state are set.
8992
*/
@@ -130,7 +133,7 @@ export interface VitestRunner {
130133
*/
131134
onAfterRunFiles?: (files: File[]) => unknown
132135
/**
133-
* Called when new context for a test is defined. Useful, if you want to add custom properties to the context.
136+
* Called when new context for a test is defined. Useful if you want to add custom properties to the context.
134137
* If you only want to define custom context, consider using "beforeAll" in "setupFiles" instead.
135138
*
136139
* This method is called for both "test" and "custom" handlers.
@@ -141,7 +144,7 @@ export interface VitestRunner {
141144
context: TaskContext<T>
142145
) => ExtendedContext<T>
143146
/**
144-
* Called, when files are imported. Can be called in two situations: when collecting tests and when importing setup files.
147+
* Called when test and setup files are imported. Can be called in two situations: when collecting tests and when importing setup files.
145148
*/
146149
importFile: (filepath: string, source: VitestRunnerImportSource) => unknown
147150
/**

0 commit comments

Comments
 (0)