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

feat: introduce the new reporter API #7069

Draft
wants to merge 39 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
38b967c
feat: introduce the new reporter API
sheremet-va Dec 11, 2024
25bae18
chore: cleanup
sheremet-va Dec 13, 2024
0998e4f
feat: introduce the new reporter API
sheremet-va Dec 11, 2024
6f0da08
chore: cleanup
sheremet-va Dec 13, 2024
64abbda
feat(reporters): add first 5/7 test run life cycles
AriPerkkio Dec 19, 2024
f3686b0
test: add initial test setup
AriPerkkio Dec 31, 2024
9cd58e9
fix: report skipped tests, prevent duplicate queued
AriPerkkio Dec 31, 2024
3f6edd5
fix: review
AriPerkkio Dec 31, 2024
1b8264a
Merge branch 'feat/new-reporter-api' of github.com:sheremet-va/vitest…
sheremet-va Jan 3, 2025
506cec5
refactor: don't allow undefined in getReportedEntity
sheremet-va Jan 3, 2025
2624054
refactor: move collecton/enqueued to the test runner
sheremet-va Jan 3, 2025
ef9a086
refactor: remove test.skipped()
sheremet-va Jan 3, 2025
10f3890
fix: correct skipped state
sheremet-va Jan 3, 2025
ebf3454
docs: cleanup
sheremet-va Jan 3, 2025
5d2bd70
docs: remove skipped from suite methods
sheremet-va Jan 3, 2025
cd291db
feat: add onTestModuleCollected
sheremet-va Jan 3, 2025
0ef6608
refactor: add events to TaskResultPack
sheremet-va Jan 3, 2025
d515785
docs: update result() docs
sheremet-va Jan 3, 2025
87d313b
docs: add state() docs
sheremet-va Jan 3, 2025
934087b
docs: fix result description
sheremet-va Jan 3, 2025
6567412
docs: update metadata docs
sheremet-va Jan 3, 2025
5e3b7cb
refactor: add event
sheremet-va Jan 3, 2025
20696a5
chore: fix ts error
sheremet-va Jan 3, 2025
ed1332e
fix: set event in typechecking
sheremet-va Jan 3, 2025
89baf8e
refactor: move log to test run
sheremet-va Jan 3, 2025
4afce13
refactor: move onFinished
sheremet-va Jan 3, 2025
4557b4b
fix: report skipped tests of suites
AriPerkkio Jan 4, 2025
3e0990e
Merge remote-tracking branch 'upstream/main' into feat/new-reporter-api
AriPerkkio Jan 4, 2025
1a74b1b
feat(reporter): `'dot'` to use new reporter API
AriPerkkio Jan 4, 2025
84ddc2f
refactor: mark readonly properties
sheremet-va Jan 4, 2025
1f03389
refactor: rename spec.module to spec.testModule
sheremet-va Jan 4, 2025
19fd301
docs: update options type, remove "reporter api" warning
sheremet-va Jan 4, 2025
be5b429
feat(reporter): summary to use new reporter API, except before & afte…
AriPerkkio Jan 4, 2025
02c0279
refactor: add comments and clarifications
sheremet-va Jan 7, 2025
1c8fb37
chore: cleanup
sheremet-va Jan 7, 2025
f6c3571
refactor: remove `TaskParser`, use new reporter API completely
AriPerkkio Jan 7, 2025
eb36354
refactor: rename new APIs
AriPerkkio Jan 7, 2025
0cef2b5
fix: resolve reporter life cycle from `onTaskUpdate` event field
AriPerkkio Jan 7, 2025
b5b962f
fix: report hooks only when they actually exist
AriPerkkio Jan 7, 2025
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
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ export default ({ mode }: { mode: string }) => {
text: 'Running Tests',
link: '/advanced/guide/tests',
},
{
text: 'Test Lifecycle',
link: '/advanced/guide/lifecycle',
},
{
text: 'Extending Reporters',
link: '/advanced/reporters',
Expand Down
97 changes: 41 additions & 56 deletions docs/advanced/api/test-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,6 @@ if (task.type === 'test') {
}
```

::: warning
We are planning to introduce a new Reporter API that will be using this API by default. For now, the Reporter API uses [runner tasks](/advanced/runner#tasks), but you can still access `TestCase` via `vitest.state.getReportedEntity` method:

```ts
import type { RunnerTestFile, TestModule, Vitest } from 'vitest/node'

class Reporter {
private vitest!: Vitest

onInit(vitest: Vitest) {
this.vitest = vitest
}

onFinished(files: RunnerTestFile[]) {
for (const file of files) {
const testModule = this.vitest.getReportedEntity(file) as TestModule
for (const test of testModule.children.allTests()) {
console.log(test) // TestCase
}
}
}
}
```
:::

## project

This references the [`TestProject`](/advanced/api/test-project) that the test belongs to.
Expand Down Expand Up @@ -124,12 +99,13 @@ Parent [suite](/advanced/api/test-suite). If the test was called directly inside

```ts
interface TaskOptions {
each: boolean | undefined
concurrent: boolean | undefined
shuffle: boolean | undefined
retry: number | undefined
repeats: number | undefined
mode: 'run' | 'only' | 'skip' | 'todo'
readonly each: boolean | undefined
readonly fails: boolean | undefined
readonly concurrent: boolean | undefined
readonly shuffle: boolean | undefined
readonly retry: number | undefined
readonly repeats: number | undefined
readonly mode: 'run' | 'only' | 'skip' | 'todo' | 'queued'
}
```

Expand All @@ -143,14 +119,6 @@ function ok(): boolean

Checks if the test did not fail the suite. If the test is not finished yet or was skipped, it will return `true`.

## skipped

```ts
function skipped(): boolean
```

Checks if the test was skipped during collection or dynamically with `ctx.skip()`.

## meta

```ts
Expand All @@ -174,10 +142,23 @@ If the test did not finish running yet, the meta will be an empty object.
## result

```ts
function result(): TestResult | undefined
function result(): TestResult
```

Test results. It will be `undefined` if test is skipped during collection, not finished yet or was just collected.
Test results. If test is not finished yet or was just collected, it will be equal to `TestResultPending`:

```ts
export interface TestResultPending {
/**
* The test was collected, but didn't finish running yet.
*/
readonly state: 'pending'
/**
* Pending tests have no errors.
*/
readonly errors: undefined
}
```

If the test was skipped, the return value will be `TestResultSkipped`:

Expand All @@ -187,15 +168,15 @@ interface TestResultSkipped {
* The test was skipped with `skip` or `todo` flag.
* You can see which one was used in the `options.mode` option.
*/
state: 'skipped'
readonly state: 'skipped'
/**
* Skipped tests have no errors.
*/
errors: undefined
readonly errors: undefined
/**
* A custom note passed down to `ctx.skip(note)`.
*/
note: string | undefined
readonly note: string | undefined
}
```

Expand All @@ -210,26 +191,26 @@ interface TestResultFailed {
/**
* The test failed to execute.
*/
state: 'failed'
readonly state: 'failed'
/**
* Errors that were thrown during the test execution.
*/
errors: TestError[]
readonly errors: ReadonlyArray<TestError>
}
```

If the test passed, the retunr value will be `TestResultPassed`:
If the test passed, the return value will be `TestResultPassed`:

```ts
interface TestResultPassed {
/**
* The test passed successfully.
*/
state: 'passed'
readonly state: 'passed'
/**
* Errors that were thrown during the test execution.
*/
errors: TestError[] | undefined
readonly errors: ReadonlyArray<TestError> | undefined
}
```

Expand All @@ -250,32 +231,36 @@ interface TestDiagnostic {
/**
* If the duration of the test is above `slowTestThreshold`.
*/
slow: boolean
readonly slow: boolean
/**
* The amount of memory used by the test in bytes.
* This value is only available if the test was executed with `logHeapUsage` flag.
*/
heap: number | undefined
readonly heap: number | undefined
/**
* The time it takes to execute the test in ms.
*/
duration: number
readonly duration: number
/**
* The time in ms when the test started.
*/
startTime: number
readonly startTime: number
/**
* The amount of times the test was retried.
*/
retryCount: number
readonly retryCount: number
/**
* The amount of times the test was repeated as configured by `repeats` option.
* This value can be lower if the test failed during the repeat and no `retry` is configured.
*/
repeatCount: number
readonly repeatCount: number
/**
* If test passed on a second retry.
*/
flaky: boolean
readonly flaky: boolean
}
```

::: info
`diagnostic()` will return `undefined` if the test did not finish running yet.
:::
10 changes: 3 additions & 7 deletions docs/advanced/api/test-collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,14 @@ for (const suite of module.children.allSuites()) {
## allTests

```ts
function allTests(
state?: TestResult['state'] | 'running'
): Generator<TestCase, undefined, void>
function allTests(state?: TestState): Generator<TestCase, undefined, void>
```

Filters all tests that are part of this collection and its children.

```ts
for (const test of module.children.allTests()) {
if (!test.result()) {
if (test.result().state === 'pending') {
console.log('test', test.fullName, 'did not finish')
}
}
Expand All @@ -77,9 +75,7 @@ You can pass down a `state` value to filter tests by the state.
## tests

```ts
function tests(
state?: TestResult['state'] | 'running'
): Generator<TestCase, undefined, void>
function tests(state?: TestState): Generator<TestCase, undefined, void>
```

Filters only the tests that are part of this collection. You can pass down a `state` value to filter tests by the state.
Expand Down
41 changes: 13 additions & 28 deletions docs/advanced/api/test-module.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,20 @@ if (task.type === 'module') {
}
```

The `TestModule` inherits all methods and properties from the [`TestSuite`](/advanced/api/test-module). This guide will only list methods and properties unique to the `TestModule`

::: warning
We are planning to introduce a new Reporter API that will be using this API by default. For now, the Reporter API uses [runner tasks](/advanced/runner#tasks), but you can still access `TestModule` via `vitest.state.getReportedEntity` method:

```ts
import type { RunnerTestFile, TestModule, Vitest } from 'vitest/node'

class Reporter {
private vitest!: Vitest

onInit(vitest: Vitest) {
this.vitest = vitest
}

onFinished(files: RunnerTestFile[]) {
for (const file of files) {
const testModule = this.vitest.state.getReportedEntity(file) as TestModule
console.log(testModule) // TestModule
}
}
}
```
::: warning Extending Suite Methods
The `TestModule` class inherits all methods and properties from the [`TestSuite`](/advanced/api/test-module). This guide will only list methods and properties unique to the `TestModule`.
:::

## moduleId

This is usually an absolute unix file path (even on Windows). It can be a virtual id if the file is not on the disk. This value corresponds to Vite's `ModuleGraph` id.

```ts
'C:/Users/Documents/project/example.test.ts' // ✅
'/Users/mac/project/example.test.ts' // ✅
'C:\\Users\\Documents\\project\\example.test.ts' // ❌
```

## diagnostic

```ts
Expand All @@ -52,23 +37,23 @@ interface ModuleDiagnostic {
/**
* The time it takes to import and initiate an environment.
*/
environmentSetupDuration: number
readonly environmentSetupDuration: number
/**
* The time it takes Vitest to setup test harness (runner, mocks, etc.).
*/
prepareDuration: number
readonly prepareDuration: number
/**
* The time it takes to import the test module.
* This includes importing everything in the module and executing suite callbacks.
*/
collectDuration: number
readonly collectDuration: number
/**
* The time it takes to import the setup module.
*/
setupDuration: number
readonly setupDuration: number
/**
* Accumulated duration of all tests and hooks in the module.
*/
duration: number
readonly duration: number
}
```
8 changes: 8 additions & 0 deletions docs/advanced/api/test-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const specification = project.createSpecification(

`createSpecification` expects resolved module ID. It doesn't auto-resolve the file or check that it exists on the file system.

## taskId

[Test module's](/advanced/api/test-suite#id) identifier.

## project

This references the [`TestProject`](/advanced/api/test-project) that the test module belongs to.
Expand All @@ -27,6 +31,10 @@ The ID of the module in Vite's module graph. Usually, it's an absolute file path
'C:\\Users\\Documents\\project\\example.test.ts' // ❌
```

## testModule

Instance of [`TestModule`](/advanced/api/test-module) assosiated with the specification. If test wasn't queued yet, this will be `undefined`.

## pool <Badge type="warning">experimental</Badge> {#pool}

The [`pool`](/config/#pool) in which the test module will run.
Expand Down
Loading
Loading