@@ -56,6 +56,374 @@ export default defineConfig({
56
56
})
57
57
```
58
58
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
+
59
427
## Exported Reporters
60
428
61
429
` vitest ` comes with a few [ built-in reporters] ( /guide/reporters ) that you can use out of the box.
0 commit comments