Skip to content

Commit 40dfad8

Browse files
authored
docs: add reported tasks docs (#6245)
1 parent 13d85bd commit 40dfad8

File tree

4 files changed

+382
-20
lines changed

4 files changed

+382
-20
lines changed

docs/advanced/reporters.md

+368
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,374 @@ export default defineConfig({
5656
})
5757
```
5858

59+
## Reported Tasks
60+
61+
::: warning
62+
This is an experimental API. Breaking changes might not follow SemVer. Please pin Vitest's version when using it.
63+
64+
You can get access to this API by calling `vitest.state.getReportedEntity(runnerTask)`:
65+
66+
```ts twoslash
67+
import type { Vitest } from 'vitest/node'
68+
import type { RunnerTestFile } from 'vitest'
69+
import type { Reporter, TestFile } from 'vitest/reporters'
70+
71+
class MyReporter implements Reporter {
72+
ctx!: Vitest
73+
74+
onInit(ctx: Vitest) {
75+
this.ctx = ctx
76+
}
77+
78+
onFinished(files: RunnerTestFile[]) {
79+
for (const fileTask of files) {
80+
const testFile = this.ctx.state.getReportedEntity(fileTask) as TestFile
81+
for (const task of testFile.children) {
82+
// ^?
83+
console.log('finished', task.type, task.fullName)
84+
}
85+
}
86+
}
87+
}
88+
```
89+
90+
We are planning to stabilize this API in Vitest 2.1.
91+
:::
92+
93+
### TestCase
94+
95+
`TestCase` represents a single test.
96+
97+
```ts
98+
declare class TestCase {
99+
readonly type = 'test' | 'custom'
100+
/**
101+
* Task instance.
102+
* @experimental Public task API is experimental and does not follow semver.
103+
*/
104+
readonly task: RunnerTestCase | RunnerCustomCase
105+
/**
106+
* The project associated with the test.
107+
*/
108+
readonly project: TestProject
109+
/**
110+
* Direct reference to the test file where the test is defined.
111+
*/
112+
readonly file: TestFile
113+
/**
114+
* Name of the test.
115+
*/
116+
readonly name: string
117+
/**
118+
* Full name of the test including all parent suites separated with `>`.
119+
*/
120+
readonly fullName: string
121+
/**
122+
* Unique identifier.
123+
* This ID is deterministic and will be the same for the same test across multiple runs.
124+
* The ID is based on the project name, file path and test position.
125+
*/
126+
readonly id: string
127+
/**
128+
* Location in the file where the test was defined.
129+
* Locations are collected only if `includeTaskLocation` is enabled in the config.
130+
*/
131+
readonly location: { line: number; column: number } | undefined
132+
/**
133+
* Parent suite. If the test was called directly inside the file, the parent will be the file.
134+
*/
135+
readonly parent: TestSuite | TestFile
136+
/**
137+
* Options that test was initiated with.
138+
*/
139+
readonly options: TaskOptions
140+
/**
141+
* Checks if the test did not fail the suite.
142+
* If the test is not finished yet or was skipped, it will return `true`.
143+
*/
144+
ok(): boolean
145+
/**
146+
* Custom metadata that was attached to the test during its execution.
147+
*/
148+
meta(): TaskMeta
149+
/**
150+
* Test results. Will be `undefined` if test is not finished yet or was just collected.
151+
*/
152+
result(): TestResult | undefined
153+
/**
154+
* Useful information about the test like duration, memory usage, etc.
155+
*/
156+
diagnostic(): TestDiagnostic | undefined
157+
}
158+
159+
export type TestResult = TestResultPassed | TestResultFailed | TestResultSkipped
160+
161+
export interface TestResultPassed {
162+
/**
163+
* The test passed successfully.
164+
*/
165+
state: 'passed'
166+
/**
167+
* Errors that were thrown during the test execution.
168+
*
169+
* **Note**: If test was retried successfully, errors will still be reported.
170+
*/
171+
errors: TestError[] | undefined
172+
}
173+
174+
export interface TestResultFailed {
175+
/**
176+
* The test failed to execute.
177+
*/
178+
state: 'failed'
179+
/**
180+
* Errors that were thrown during the test execution.
181+
*/
182+
errors: TestError[]
183+
}
184+
185+
export interface TestResultSkipped {
186+
/**
187+
* The test was skipped with `only`, `skip` or `todo` flag.
188+
* You can see which one was used in the `mode` option.
189+
*/
190+
state: 'skipped'
191+
/**
192+
* Skipped tests have no errors.
193+
*/
194+
errors: undefined
195+
}
196+
197+
export interface TestDiagnostic {
198+
/**
199+
* The amount of memory used by the test in bytes.
200+
* This value is only available if the test was executed with `logHeapUsage` flag.
201+
*/
202+
heap: number | undefined
203+
/**
204+
* The time it takes to execute the test in ms.
205+
*/
206+
duration: number
207+
/**
208+
* The time in ms when the test started.
209+
*/
210+
startTime: number
211+
/**
212+
* The amount of times the test was retried.
213+
*/
214+
retryCount: number
215+
/**
216+
* The amount of times the test was repeated as configured by `repeats` option.
217+
* This value can be lower if the test failed during the repeat and no `retry` is configured.
218+
*/
219+
repeatCount: number
220+
/**
221+
* If test passed on a second retry.
222+
*/
223+
flaky: boolean
224+
}
225+
```
226+
227+
### TestSuite
228+
229+
`TestSuite` represents a single suite that contains tests and other suites.
230+
231+
```ts
232+
declare class TestSuite {
233+
readonly type = 'suite'
234+
/**
235+
* Task instance.
236+
* @experimental Public task API is experimental and does not follow semver.
237+
*/
238+
readonly task: RunnerTestSuite
239+
/**
240+
* The project associated with the test.
241+
*/
242+
readonly project: TestProject
243+
/**
244+
* Direct reference to the test file where the suite is defined.
245+
*/
246+
readonly file: TestFile
247+
/**
248+
* Name of the suite.
249+
*/
250+
readonly name: string
251+
/**
252+
* Full name of the suite including all parent suites separated with `>`.
253+
*/
254+
readonly fullName: string
255+
/**
256+
* Unique identifier.
257+
* This ID is deterministic and will be the same for the same test across multiple runs.
258+
* The ID is based on the project name, file path and test position.
259+
*/
260+
readonly id: string
261+
/**
262+
* Location in the file where the suite was defined.
263+
* Locations are collected only if `includeTaskLocation` is enabled in the config.
264+
*/
265+
readonly location: { line: number; column: number } | undefined
266+
/**
267+
* Collection of suites and tests that are part of this suite.
268+
*/
269+
readonly children: TaskCollection
270+
/**
271+
* Options that the suite was initiated with.
272+
*/
273+
readonly options: TaskOptions
274+
}
275+
```
276+
277+
### TestFile
278+
279+
`TestFile` represents a single file that contains suites and tests.
280+
281+
```ts
282+
declare class TestFile extends SuiteImplementation {
283+
readonly type = 'file'
284+
/**
285+
* Task instance.
286+
* @experimental Public task API is experimental and does not follow semver.
287+
*/
288+
readonly task: RunnerTestFile
289+
/**
290+
* Collection of suites and tests that are part of this file.
291+
*/
292+
readonly children: TestCollection
293+
/**
294+
* This is usually an absolute Unix file path.
295+
* It can be a virtual id if the file is not on the disk.
296+
* This value corresponds to Vite's `ModuleGraph` id.
297+
*/
298+
readonly moduleId: string
299+
/**
300+
* Useful information about the file like duration, memory usage, etc.
301+
* If the file was not executed yet, all diagnostic values will return `0`.
302+
*/
303+
diagnostic(): FileDiagnostic
304+
}
305+
306+
export interface FileDiagnostic {
307+
/**
308+
* The time it takes to import and initiate an environment.
309+
*/
310+
environmentSetupDuration: number
311+
/**
312+
* The time it takes Vitest to setup test harness (runner, mocks, etc.).
313+
*/
314+
prepareDuration: number
315+
/**
316+
* The time it takes to import the test file.
317+
* This includes importing everything in the file and executing suite callbacks.
318+
*/
319+
collectDuration: number
320+
/**
321+
* The time it takes to import the setup file.
322+
*/
323+
setupDuration: number
324+
/**
325+
* Accumulated duration of all tests and hooks in the file.
326+
*/
327+
duration: number
328+
}
329+
```
330+
331+
### TestCollection
332+
333+
`TestCollection` represents a collection of suites and tests. It also provides useful methods to iterate over itself.
334+
335+
```ts
336+
declare class TestCollection {
337+
/**
338+
* Returns the test or suite at a specific index in the array.
339+
*/
340+
at(index: number): TestCase | TestSuite | undefined
341+
/**
342+
* The number of tests and suites in the collection.
343+
*/
344+
size: number
345+
/**
346+
* Returns the collection in array form for easier manipulation.
347+
*/
348+
array(): (TestCase | TestSuite)[]
349+
/**
350+
* Filters all suites that are part of this collection and its children.
351+
*/
352+
allSuites(): IterableIterator<TestSuite>
353+
/**
354+
* Filters all tests that are part of this collection and its children.
355+
*/
356+
allTests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>
357+
/**
358+
* Filters only the tests that are part of this collection.
359+
*/
360+
tests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>
361+
/**
362+
* Filters only the suites that are part of this collection.
363+
*/
364+
suites(): IterableIterator<TestSuite>;
365+
[Symbol.iterator](): IterableIterator<TestSuite | TestCase>
366+
}
367+
```
368+
369+
For example, you can iterate over all tests inside a file by calling `testFile.children.allTests()`:
370+
371+
```ts
372+
function onFileCollected(testFile: TestFile): void {
373+
console.log('collecting tests in', testFile.moduleId)
374+
375+
// iterate over all tests and suites in the file
376+
for (const task of testFile.children.allTests()) {
377+
console.log('collected', task.type, task.fullName)
378+
}
379+
}
380+
```
381+
382+
### TestProject
383+
384+
`TestProject` is a project assosiated with the file. Every test and suite inside that file will reference the same project.
385+
386+
Project is useful to get the configuration or provided context.
387+
388+
```ts
389+
declare class TestProject {
390+
/**
391+
* The global vitest instance.
392+
* @experimental The public Vitest API is experimental and does not follow semver.
393+
*/
394+
readonly vitest: Vitest
395+
/**
396+
* The workspace project this test project is associated with.
397+
* @experimental The public Vitest API is experimental and does not follow semver.
398+
*/
399+
readonly workspaceProject: WorkspaceProject
400+
/**
401+
* Resolved project configuration.
402+
*/
403+
readonly config: ResolvedProjectConfig
404+
/**
405+
* Resolved global configuration. If there are no workspace projects, this will be the same as `config`.
406+
*/
407+
readonly globalConfig: ResolvedConfig
408+
/**
409+
* Serialized project configuration. This is the config that tests receive.
410+
*/
411+
get serializedConfig(): SerializedConfig
412+
/**
413+
* The name of the project or an empty string if not set.
414+
*/
415+
name(): string
416+
/**
417+
* Custom context provided to the project.
418+
*/
419+
context(): ProvidedContext
420+
/**
421+
* Provide a custom serializable context to the project. This context will be available for tests once they run.
422+
*/
423+
provide<T extends keyof ProvidedContext & string>(key: T, value: ProvidedContext[T]): void
424+
}
425+
```
426+
59427
## Exported Reporters
60428

61429
`vitest` comes with a few [built-in reporters](/guide/reporters) that you can use out of the box.

packages/vitest/src/node/reported-workspace-project.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class TestProject {
5252
}
5353

5454
/**
55-
* Provide a custom context to the project. This context will be available for tests once they run.
55+
* Provide a custom serializable context to the project. This context will be available for tests once they run.
5656
*/
5757
public provide<T extends keyof ProvidedContext & string>(
5858
key: T,

packages/vitest/src/node/reporters/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export {
2929
export type { BaseReporter, Reporter }
3030

3131
export { TestCase, TestFile, TestSuite } from './reported-tasks'
32+
export type { TestProject } from '../reported-workspace-project'
3233
export type {
3334
TestCollection,
3435

0 commit comments

Comments
 (0)