FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

docs: deprecate old context augmentation and recommend test.extend by sheremet-va · Pull Request #7703 · vitest-dev/vitest · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .md  (4) .ts  (4) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
2 changes: 1 addition & 1 deletion docs/advanced/runner.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ interface Test<ExtraContext = object> extends TaskBase {
*/
file: File
/**
* Whether the task was skipped by calling `t.skip()`.
* Whether the task was skipped by calling `context.skip()`.
*/
pending?: boolean
/**
Expand Down
10 changes: 0 additions & 10 deletions docs/api/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1279,16 +1279,6 @@ test('performs an organization query', async () => {

::: tip
This hook is always called in reverse order and is not affected by [`sequence.hooks`](/config/#sequence-hooks) option.

<!-- TODO: should it be called? https://github.com/vitest-dev/vitest/pull/7069 -->
Note that this hook is not called if test was skipped with a dynamic `ctx.skip()` call:

```ts{2}
test('skipped dynamically', (t) => {
onTestFinished(() => {}) // not called
t.skip()
})
```
:::

### onTestFailed
Expand Down
7 changes: 7 additions & 0 deletions docs/guide/cli-generated.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,13 @@ Omit annotation lines from the output (default: `false`)

Print basic prototype Object and Array (default: `true`)

### diff.maxDepth

- **CLI:** `--diff.maxDepth <maxDepth>`
- **Config:** [diff.maxDepth](/config/#diff-maxdepth)

Limit the depth to recurse when printing nested objects (default: `20`)

### diff.truncateThreshold

- **CLI:** `--diff.truncateThreshold <threshold>`
Expand Down
112 changes: 82 additions & 30 deletions docs/guide/test-context.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ The first argument for each test callback is a test context.
```ts
import { it } from 'vitest'

it('should work', (ctx) => {
it('should work', ({ task }) => {
// prints name of the test
console.log(ctx.task.name)
console.log(task.name)
})
```

## Built-in Test Context

#### `context.task`
#### `task`

A readonly object containing metadata about the test.

#### `context.expect`
#### `expect`

The `expect` API bound to the current test:

Expand All @@ -52,7 +52,12 @@ it.concurrent('math is hard', ({ expect }) => {
})
```

#### `context.skip`
#### `skip`

```ts
function skip(note?: string): never
function skip(condition: boolean, note?: string): void
```

Skips subsequent test execution and marks test as skipped:

Expand All @@ -65,6 +70,23 @@ it('math is hard', ({ skip }) => {
})
```

Since Vitest 3.1, it accepts a boolean parameter to skip the test conditionally:

```ts
it('math is hard', ({ skip, mind }) => {
skip(mind === 'foggy')
expect(2 + 2).toBe(5)
})
```

#### `onTestFailed`

The [`onTestFailed`](/api/#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.

#### `onTestFinished`

The [`onTestFinished`](/api/#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.

## Extend Test Context

Vitest provides two different ways to help you extend the test context.
Expand All @@ -73,15 +95,15 @@ Vitest provides two different ways to help you extend the test context.

Like [Playwright](https://playwright.dev/docs/api/class-test#test-extend), you can use this method to define your own `test` API with custom fixtures and reuse it anywhere.

For example, we first create `myTest` with two fixtures, `todos` and `archive`.
For example, we first create the `test` collector with two fixtures: `todos` and `archive`.

```ts [my-test.ts]
import { test } from 'vitest'
import { test as baseTest } from 'vitest'

const todos = []
const archive = []

export const myTest = test.extend({
export const test = baseTest.extend({
todos: async ({}, use) => {
// setup the fixture before each test function
todos.push(1, 2, 3)
Expand All @@ -100,16 +122,16 @@ Then we can import and use it.

```ts [my-test.test.ts]
import { expect } from 'vitest'
import { myTest } from './my-test.js'
import { test } from './my-test.js'

myTest('add items to todos', ({ todos }) => {
test('add items to todos', ({ todos }) => {
expect(todos.length).toBe(3)

todos.push(4)
expect(todos.length).toBe(4)
})

myTest('move items from todos to archive', ({ todos, archive }) => {
test('move items from todos to archive', ({ todos, archive }) => {
expect(todos.length).toBe(3)
expect(archive.length).toBe(0)

Expand All @@ -119,10 +141,12 @@ myTest('move items from todos to archive', ({ todos, archive }) => {
})
```

We can also add more fixtures or override existing fixtures by extending `myTest`.
We can also add more fixtures or override existing fixtures by extending our `test`.

```ts
export const myTest2 = myTest.extend({
import { test as todosTest } from './my-test.js'

export const test = todosTest.extend({
settings: {
// ...
}
Expand All @@ -134,34 +158,35 @@ export const myTest2 = myTest.extend({
Vitest runner will smartly initialize your fixtures and inject them into the test context based on usage.

```ts
import { test } from 'vitest'
import { test as baseTest } from 'vitest'

async function todosFn({ task }, use) {
await use([1, 2, 3])
}

const myTest = test.extend({
todos: todosFn,
const test = baseTest.extend<{
todos: number[]
archive: number[]
}>({
todos: async ({ task }, use) => {
await use([1, 2, 3])
},
archive: []
})

// todosFn will not run
myTest('', () => {})
myTest('', ({ archive }) => {})
// todos will not run
test('skip', () => {})
test('skip', ({ archive }) => {})

// todosFn will run
myTest('', ({ todos }) => {})
// todos will run
test('run', ({ todos }) => {})
```

::: warning
When using `test.extend()` with fixtures, you should always use the object destructuring pattern `{ todos }` to access context both in fixture function and test function.

```ts
myTest('context must be destructured', (context) => { // [!code --]
test('context must be destructured', (context) => { // [!code --]
expect(context.todos.length).toBe(2)
})

myTest('context must be destructured', ({ todos }) => { // [!code ++]
test('context must be destructured', ({ todos }) => { // [!code ++]
expect(todos.length).toBe(2)
})
```
Expand Down Expand Up @@ -316,19 +341,46 @@ interface MyFixtures {
archive: number[]
}

const myTest = test.extend<MyFixtures>({
const test = baseTest.extend<MyFixtures>({
todos: [],
archive: []
})

myTest('types are defined correctly', ({ todos, archive }) => {
test('types are defined correctly', ({ todos, archive }) => {
expectTypeOf(todos).toEqualTypeOf<number[]>()
expectTypeOf(archive).toEqualTypeOf<number[]>()
})
```

::: info Type Infering
Note that Vitest doesn't support infering the types when the `use` function is called. It is always preferable to pass down the whole context type as the generic type when `test.extend` is called:

```ts
import { test as baseTest } from 'vitest'

const test = baseTest.extend<{
todos: number[]
schema: string
}>({
todos: ({ schema }, use) => use([]),
schema: 'test'
})

test('types are correct', ({
todos, // number[]
schema, // string
}) => {
// ...
})
```
:::

### `beforeEach` and `afterEach`

::: danger Deprecated
This is an outdated way of extending context and it will not work when the `test` is extended with `test.extend`.
:::

The contexts are different for each test. You can access and extend them within the `beforeEach` and `afterEach` hooks.

```ts
Expand All @@ -346,7 +398,7 @@ it('should work', ({ foo }) => {

#### TypeScript

To provide property types for all your custom contexts, you can aggregate the `TestContext` type by adding
To provide property types for all your custom contexts, you can augment the `TestContext` type by adding

```ts
declare module 'vitest' {
Expand Down
2 changes: 1 addition & 1 deletion packages/runner/src/types/tasks.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export interface TaskResult {
/** @private */
note?: string
/**
* Whether the task was skipped by calling `t.skip()`.
* Whether the task was skipped by calling `context.skip()`.
* @internal
*/
pending?: boolean
Expand Down
8 changes: 4 additions & 4 deletions test/cli/fixtures/fails/skip-conditional.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { expect, it } from 'vitest';

it('skips correctly', (t) => {
t.skip(true)
it('skips correctly', ({ skip }) => {
skip(true)
expect.unreachable()
})

it('doesnt skip correctly', (t) => {
t.skip(false)
it('doesnt skip correctly', ({ skip }) => {
skip(false)
throw new Error('doesnt skip')
})
8 changes: 4 additions & 4 deletions test/core/test/on-finished.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ it('on-finished regular', () => {
collected.push(2)
})

it('on-finished context', (t) => {
it('on-finished context', ({ onTestFinished }) => {
collected.push(4)
t.onTestFinished(() => {
onTestFinished(() => {
collected.push(6)
})
collected.push(5)
Expand All @@ -29,9 +29,9 @@ it.fails('failed finish', () => {
collected.push(null)
})

it.fails('failed finish context', (t) => {
it.fails('failed finish context', ({ onTestFinished }) => {
collected.push(10)
t.onTestFinished(() => {
onTestFinished(() => {
collected.push(12)
})
collected.push(11)
Expand Down
12 changes: 6 additions & 6 deletions test/reporters/fixtures/default/a.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ describe('a failed', () => {
})

describe('a skipped', () => {
test('skipped with note', (t) => {
t.skip('reason')
test('skipped with note', ({ skip }) => {
skip('reason')
})

test('condition', (t) => {
t.skip(true)
test('condition', ({ skip }) => {
skip(true)
})

test('condition with note', (t) => {
t.skip(true, 'note')
test('condition with note', ({ skip }) => {
skip(true, 'note')
})
})

Back | FazBrowse Home | New Git URL