Passer au contenu

Contexte de Test

Inspiré par Playwright Fixtures, le contexte de test de Vitest vous permet de définir des utilitaires, des états et des fixtures qui peuvent être utilisés dans vos tests.

Utilisation

Le premier argument pour chaque callback de test est un contexte de test.

import { it } from 'vitest'
it('should work', (ctx) => {
// imprime le nom du test
console.log(ctx.task.name)
})

Contexte de Test Intégré

context.task

Un objet en lecture seule contenant des métadonnées sur le test.

context.expect

L’API expect liée au test actuel :

import { it } from 'vitest'
it('math is easy', ({ expect }) => {
expect(2 + 2).toBe(4)
})

Cette API est utile pour exécuter des tests de snapshot en parallèle car l’expect global ne peut pas les suivre :

import { it } from 'vitest'
it.concurrent('math is easy', ({ expect }) => {
expect(2 + 2).toMatchInlineSnapshot()
})
it.concurrent('math is hard', ({ expect }) => {
expect(2 * 2).toMatchInlineSnapshot()
})

context.skip

Ignore l’exécution des tests suivants et marque le test comme sauté :

import { expect, it } from 'vitest'
it('math is hard', ({ skip }) => {
skip()
expect(2 + 2).toBe(5)
})

Étendre le Contexte de Test

Vitest fournit deux façons différentes de vous aider à étendre le contexte de test.

test.extend

Comme Playwright, vous pouvez utiliser cette méthode pour définir votre propre API test avec des fixtures personnalisées et la réutiliser n’importe où.

Par exemple, nous créons d’abord myTest avec deux fixtures, todos et archive.

my-test.ts
import { test } from 'vitest'
const todos = []
const archive = []
export const myTest = test.extend({
todos: async ({}, use) => {
// configuration de la fixture avant chaque fonction de test
todos.push(1, 2, 3)
// utilisation de la valeur de la fixture
await use(todos)
// nettoyage de la fixture après chaque fonction de test
todos.length = 0
},
archive
})

Ensuite, nous pouvons l’importer et l’utiliser.

import { expect } from 'vitest'
import { myTest } from './my-test.js'
myTest('ajouter des éléments aux todos', ({ todos }) => {
expect(todos.length).toBe(3)
todos.push(4)
expect(todos.length).toBe(4)
})
myTest('déplacer des éléments des todos vers l\'archive', ({ todos, archive }) => {
expect(todos.length).toBe(3)
expect(archive.length).toBe(0)
archive.push(todos.pop())
expect(todos.length).toBe(2)
expect(archive.length).toBe(1)
})

Nous pouvons également ajouter plus de fixtures ou remplacer les fixtures existantes en étendant myTest.

export const myTest2 = myTest.extend({
settings: {
// ...
}
})

Initialisation des Fixtures

Le runner de Vitest initialisera intelligemment vos fixtures et les injectera dans le contexte de test en fonction de leur utilisation.

import { test } from 'vitest'
async function todosFn({ task }, use) {
await use([1, 2, 3])
}
const myTest = test.extend({
todos: todosFn,
archive: []
})
// todosFn ne s'exécutera pas
myTest('', () => {})
myTest('', ({ archive }) => {})
// todosFn s'exécutera
myTest('', ({ todos }) => {})

Fixture Automatique

Vitest prend également en charge la syntaxe de tuple pour les fixtures, vous permettant de passer des options pour chaque fixture. Par exemple, vous pouvez l’utiliser pour initialiser explicitement une fixture, même si elle n’est pas utilisée dans les tests.

import { test as base } from 'vitest'
const test = base.extend({
fixture: [
async ({}, use) => {
// cette fonction s'exécutera
setup()
await use()
teardown()
},
{ auto: true } // Marquer comme une fixture automatique
],
})
test('', () => {})

TypeScript

Pour fournir des types de fixture pour tous vos contextes personnalisés, vous pouvez passer le type des fixtures comme générique.

interface MyFixtures {
todos: number[]
archive: number[]
}
const myTest = test.extend<MyFixtures>({
todos: [],
archive: []
})
myTest('', (context) => {
expectTypeOf(context.todos).toEqualTypeOf<number[]>()
expectTypeOf(context.archive).toEqualTypeOf<number[]>()
})

beforeEach et afterEach

Les contextes sont différents pour chaque test. Vous pouvez y accéder et les étendre dans les hooks beforeEach et afterEach.

import { beforeEach, it } from 'vitest'
beforeEach(async (context) => {
// étendre le contexte
context.foo = 'bar'
})
it('should work', ({ foo }) => {
console.log(foo) // 'bar'
})

TypeScript

Pour fournir des types de propriétés pour tous vos contextes personnalisés, vous pouvez agréger le type TestContext en ajoutant

declare module 'vitest' {
export interface TestContext {
foo?: string
}
}

Si vous souhaitez fournir des types de propriétés uniquement pour des hooks spécifiques beforeEach, afterEach, it et test, vous pouvez passer le type comme générique.

interface LocalTestContext {
foo: string
}
beforeEach<LocalTestContext>(async (context) => {
// typeof context est 'TestContext & LocalTestContext'
context.foo = 'bar'
})
it<LocalTestContext>('should work', ({ foo }) => {
// typeof foo est 'string'
console.log(foo) // 'bar'
})