Skip to content
Vitest 3
Main Navigation Guide & APIConfigurationMode NavigateurAPI avancée
3.2.0
2.1.9
1.6.1
0.34.6

Français

English
简体中文
繁體中文
Español
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Français

English
简体中文
繁體中文
Español
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Apparence

Sidebar Navigation

Introduction

Pourquoi Vitest

Démarrage

Fonctionnalités

Configuration de Vitest

API

Référence de l'API des Tests

Fonctions Mocks

vi

expect

expectTypeOf

assert

assertType

Guide

Interface en ligne de commande (CLI)

Filtrage des tests

Projets de Test

Rapporteurs

Couverture de code

Instantanés

Simulation

Parallélisme

Tests de type

Interface utilisateur de Vitest

Tests in-source

Contexte de test

Annotations de test

Environnement de Test

Étendre les Matchers

Intégrations IDE

Débogage

Erreurs courantes

Guide de migration

Migration vers Vitest 3.0

Migration depuis Jest

Performance

Analyse des performances des tests

Amélioration des performances

Mode Navigateur

API avancée

Comparaison avec d'autres exécuteurs de tests

Sur cette page

Référence de l'API des Tests ​

Les types suivants sont utilisés dans les signatures de type ci-dessous :

ts
type Awaitable<T> = T | PromiseLike<T>;
type TestFunction = () => Awaitable<void>;

interface TestOptions {
  /**
   * Le test échouera si son exécution dépasse le temps imparti.
   */
  timeout?: number;
  /**
   * Retentera le test un nombre spécifique de fois s'il échoue.
   *
   * @default 0
   */
  retry?: number;
  /**
   * Répétera le même test plusieurs fois, même s'il échoue à chaque fois.
   * Si l'option "retry" est activée et que le test échoue, chaque tentative sera utilisée à chaque cycle.
   * Utile pour déboguer les défaillances aléatoires.
   *
   * @default 0
   */
  repeats?: number;
}

Lorsqu'une fonction de test renvoie une promesse, le runner attendra sa résolution pour collecter les attentes asynchrones. Si la promesse est rejetée, le test échouera.

TIP

Dans Jest, TestFunction peut aussi être de type (done: DoneCallback) => void. Si cette forme est utilisée, le test ne se terminera pas tant que done n'aura pas été appelé. Vous pouvez obtenir le même résultat en utilisant une fonction async. Voir la section Migration guide Done Callback pour plus d'informations.

Vous pouvez définir des options en chaînant des propriétés à une fonction :

ts
import { test } from 'vitest';

test.skip('skipped test', () => {
  // some logic that fails right now
});

test.concurrent.skip('skipped concurrent test', () => {
  // some logic that fails right now
});

Vous pouvez également fournir un objet comme deuxième argument :

ts
import { test } from 'vitest';

test('skipped test', { skip: true }, () => {
  // some logic that fails right now
});

test('skipped concurrent test', { skip: true, concurrent: true }, () => {
  // some logic that fails right now
});

Les deux méthodes fonctionnent exactement de la même manière. Le choix de l'une ou de l'autre est purement stylistique.

Notez que si vous fournissez le délai d'attente comme dernier argument, vous ne pouvez plus utiliser les options :

ts
import { test } from 'vitest';

// ✅ cela fonctionne
test.skip('heavy test', () => {
  // ...
}, 10_000);

// ❌ cela ne fonctionne pas
test(
  'heavy test',
  { skip: true },
  () => {
    // ...
  },
  10_000
);

Cependant, vous pouvez fournir un délai d'attente à l'intérieur de l'objet d'options :

ts
import { test } from 'vitest';

// ✅ cela fonctionne
test('heavy test', { skip: true, timeout: 10_000 }, () => {
  // ...
});

test ​

  • Alias : it

test définit un ensemble d'attentes associées. Il prend en paramètres le nom du test et une fonction contenant les attentes à vérifier.

Optionnellement, vous pouvez spécifier un délai d'attente (en millisecondes) pour définir la durée maximale avant l'arrêt. La valeur par défaut est de 5 secondes et peut être configurée globalement avec testTimeout.

ts
import { expect, test } from 'vitest';

test('should work as expected', () => {
  expect(Math.sqrt(4)).toBe(2);
});

test.extend ​

  • Alias : it.extend

Utilisez test.extend pour étendre le contexte de test avec des fixtures personnalisées. Cela renverra un nouveau test qui est également extensible, vous permettant ainsi de composer davantage de fixtures ou de remplacer celles existantes en l'étendant selon vos besoins. Voir Étendre le contexte de test pour plus d'informations.

ts
import { expect, test } from 'vitest';

const todos = [];
const archive = [];

const myTest = test.extend({
  todos: async ({ task }, use) => {
    todos.push(1, 2, 3);
    await use(todos);
    todos.length = 0;
  },
  archive,
});

myTest('add item', ({ todos }) => {
  expect(todos.length).toBe(3);

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

test.skip ​

  • Alias : it.skip

Si vous souhaitez ignorer l'exécution de certains tests sans supprimer leur code, vous pouvez utiliser test.skip pour les empêcher de s'exécuter.

ts
import { assert, test } from 'vitest';

test.skip('skipped test', () => {
  // Test ignoré, pas d'erreur
  assert.equal(Math.sqrt(4), 3);
});

Vous pouvez également ignorer un test en appelant skip sur son contexte dynamiquement :

ts
import { assert, test } from 'vitest';

test('skipped test', context => {
  context.skip();
  // Test ignoré, pas d'erreur
  assert.equal(Math.sqrt(4), 3);
});

Depuis Vitest 3.1, si la condition est inconnue, vous pouvez la fournir à la méthode skip comme premier argument :

ts
import { assert, test } from 'vitest';

test('skipped test', context => {
  context.skip(Math.random() < 0.5, 'optional message');
  // Test ignoré, pas d'erreur
  assert.equal(Math.sqrt(4), 3);
});

test.skipIf ​

  • Alias : it.skipIf

Dans certains cas, vous pouvez être amené à exécuter des tests plusieurs fois dans des environnements différents, et certains tests pourraient être spécifiques à l'environnement. Au lieu d'envelopper le code de test avec une condition if, vous pouvez utiliser test.skipIf pour ignorer le test si la condition est vraie.

ts
import { assert, test } from 'vitest';

const isDev = process.env.NODE_ENV === 'development';

test.skipIf(isDev)('prod only test', () => {
  // ce test ne s'exécute qu'en production
});

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

test.runIf ​

  • Alias : it.runIf

L'opposé de test.skipIf.

ts
import { assert, test } from 'vitest';

const isDev = process.env.NODE_ENV === 'development';

test.runIf(isDev)('dev only test', () => {
  // ce test ne s'exécute qu'en développement
});

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

test.only ​

  • Alias : it.only

Utilisez test.only pour n'exécuter que certains tests dans une suite donnée. C'est utile lors du débogage.

Optionnellement, vous pouvez fournir un délai d'attente (en millisecondes) pour spécifier combien de temps attendre avant de terminer. La valeur par défaut est de 5 secondes et peut être configurée globalement avec testTimeout.

ts
import { assert, test } from 'vitest';

test.only('test', () => {
  // Seul ce test (et les autres marqués avec only) sont exécutés
  assert.equal(Math.sqrt(4), 2);
});

Il est parfois très utile d'exécuter des tests only dans un certain fichier, en ignorant tous les autres tests de l'ensemble de la suite de tests, afin de ne pas surcharger la sortie.

Pour ce faire, exécutez vitest avec le fichier contenant les tests concernés.

# vitest interesting.test.ts

test.concurrent ​

  • Alias : it.concurrent

test.concurrent indique que les tests consécutifs doivent être exécutés en parallèle. Il prend en paramètres le nom du test, une fonction asynchrone contenant les tests à exécuter, et un délai d'attente optionnel (en millisecondes).

ts
import { describe, test } from 'vitest';

// Les deux tests marqués comme concurrents seront exécutés en parallèle
describe('suite', () => {
  test('serial test', async () => {
    /* ... */
  });
  test.concurrent('concurrent test 1', async () => {
    /* ... */
  });
  test.concurrent('concurrent test 2', async () => {
    /* ... */
  });
});

test.skip, test.only et test.todo fonctionnent avec les tests concurrents. Toutes les combinaisons suivantes sont valides :

ts
test.concurrent(/* ... */);
test.skip.concurrent(/* ... */); // ou test.concurrent.skip(/* ... */)
test.only.concurrent(/* ... */); // ou test.concurrent.only(/* ... */)
test.todo.concurrent(/* ... */); // ou test.concurrent.todo(/* ... */)

Lors de l'exécution de tests concurrents, les instantanés (Snapshots) et les assertions doivent utiliser expect du Contexte de Test local pour s'assurer que le bon test est détecté.

ts
test.concurrent('test 1', async ({ expect }) => {
  expect(foo).toMatchSnapshot();
});
test.concurrent('test 2', async ({ expect }) => {
  expect(foo).toMatchSnapshot();
});

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

test.sequential ​

  • Alias : it.sequential

test.sequential marque un test comme séquentiel. C'est utile si vous voulez exécuter des tests en séquence au sein de describe.concurrent ou avec l'option de commande --sequence.concurrent.

ts
import { describe, test } from 'vitest';

// avec l'option de configuration { sequence: { concurrent: true } }
test('concurrent test 1', async () => {
  /* ... */
});
test('concurrent test 2', async () => {
  /* ... */
});

test.sequential('sequential test 1', async () => {
  /* ... */
});
test.sequential('sequential test 2', async () => {
  /* ... */
});

// dans une suite concurrente
describe.concurrent('suite', () => {
  test('concurrent test 1', async () => {
    /* ... */
  });
  test('concurrent test 2', async () => {
    /* ... */
  });

  test.sequential('sequential test 1', async () => {
    /* ... */
  });
  test.sequential('sequential test 2', async () => {
    /* ... */
  });
});

test.todo ​

  • Alias : it.todo

Utilisez test.todo pour marquer des tests à implémenter plus tard. Ces tests apparaîtront dans le rapport, vous indiquant ainsi le nombre de tests qu'il vous reste à implémenter.

ts
// Une entrée sera affichée dans le rapport pour ce test
test.todo('unimplemented test');

test.fails ​

  • Alias : it.fails

Utilisez test.fails pour indiquer qu'une assertion échouera explicitement.

ts
import { expect, test } from 'vitest';

function myAsyncFunc() {
  return new Promise(resolve => resolve(1));
}
test.fails('fail test', async () => {
  await expect(myAsyncFunc()).rejects.toBe(1);
});

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

test.each ​

  • Alias : it.each

TIP

Bien que test.each soit fourni pour la compatibilité Jest, Vitest dispose également de test.for qui offre une fonctionnalité supplémentaire pour l'intégration de TestContext.

Utilisez test.each lorsque vous avez besoin d'exécuter le même test avec des variables différentes. Vous pouvez injecter des paramètres en utilisant le formatage printf dans le nom du test, en respectant l'ordre des paramètres de la fonction de test.

  • %s : chaîne de caractères
  • %d : nombre
  • %i : entier
  • %f : valeur à virgule flottante
  • %j : json
  • %o : objet
  • %# : index de cas de test basé sur 0
  • %$ : index de cas de test basé sur 1
  • %% : un seul signe pourcentage ('%')
ts
import { expect, test } from 'vitest';

test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
  expect(a + b).toBe(expected);
});

// cela retournera
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3

Vous pouvez également accéder aux propriétés d'objet et aux éléments de tableau avec le préfixe $:

ts
test.each([
  { a: 1, b: 1, expected: 2 },
  { a: 1, b: 2, expected: 3 },
  { a: 2, b: 1, expected: 3 },
])('add($a, $b) -> $expected', ({ a, b, expected }) => {
  expect(a + b).toBe(expected);
});

// cela retournera
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3

test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add($0, $1) -> $2', (a, b, expected) => {
  expect(a + b).toBe(expected);
});

// cela retournera
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3

Vous pouvez également accéder aux attributs d'objet avec ., si vous utilisez des objets comme arguments :

ts
test.each`
  a             | b      | expected
  ${{ val: 1 }} | ${'b'} | ${'1b'}
  ${{ val: 2 }} | ${'b'} | ${'2b'}
  ${{ val: 3 }} | ${'b'} | ${'3b'}
`('add($a.val, $b) -> $expected', ({ a, b, expected }) => {
  expect(a.val + b).toBe(expected);
});

// cela retournera
// ✓ add(1, b) -> 1b
// ✓ add(2, b) -> 2b
// ✓ add(3, b) -> 3b

À partir de Vitest 0.25.3, vous pouvez également utiliser une table de chaînes de caractères de modèle.

  • La première ligne doit contenir les noms de colonnes, séparés par | ;
  • Une ou plusieurs lignes de données suivantes fournies sous forme d'expressions littérales de modèle utilisant la syntaxe ${value}.
ts
import { expect, test } from 'vitest';

test.each`
  a             | b      | expected
  ${1}          | ${1}   | ${2}
  ${'a'}        | ${'b'} | ${'ab'}
  ${[]}         | ${'b'} | ${'b'}
  ${{}}         | ${'b'} | ${'[object Object]b'}
  ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
`('returns $expected when $a is added $b', ({ a, b, expected }) => {
  expect(a + b).toBe(expected);
});

TIP

Vitest traite les $values avec la méthode format de Chai. Si la valeur est trop tronquée, vous pouvez augmenter chaiConfig.truncateThreshold dans votre fichier de configuration.

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

test.for ​

  • Alias : it.for

Alternative à test.each permettant de fournir TestContext.

La différence avec test.each réside dans la manière dont les tableaux sont fournis dans les arguments. Les arguments non-tableau de test.for (y compris l'utilisation de chaînes de caractères de modèle) fonctionnent exactement de la même manière que pour test.each.

ts
// `each` déstructure les tableaux
test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => { 
  expect(a + b).toBe(expected);
});

// `for` ne déstructure pas les tableaux (notez les crochets autour des arguments)
test.for([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add(%i, %i) -> %i', ([a, b, expected]) => { 
  expect(a + b).toBe(expected);
});

Le 2ème argument est TestContext et peut être utilisé pour les instantanés concurrents, par exemple :

ts
test.concurrent.for([
  [1, 1],
  [1, 2],
  [2, 1],
])('add(%i, %i)', ([a, b], { expect }) => {
  expect(a + b).matchSnapshot();
});

bench ​

  • Type : (name: string | Function, fn: BenchFunction, options?: BenchOptions) => void

bench définit un benchmark. Dans les termes de Vitest, un benchmark est une fonction qui définit une série d'opérations. Vitest exécute cette fonction plusieurs fois pour afficher différents résultats de performance.

Vitest utilise la bibliothèque tinybench en interne, héritant de toutes ses options qui peuvent être passées comme troisième argument.

ts
import { bench } from 'vitest';

bench(
  'normal sorting',
  () => {
    const x = [1, 5, 4, 2, 3];
    x.sort((a, b) => {
      return a - b;
    });
  },
  { time: 1000 }
);
ts
export interface Options {
  /**
   * Temps nécessaire pour exécuter une tâche de benchmark (millisecondes).
   * @default 500
   */
  time?: number;

  /**
   * Nombre de fois qu'une tâche doit s'exécuter même si le temps alloué est écoulé.
   * @default 10
   */
  iterations?: number;

  /**
   * Fonction pour obtenir l'horodatage actuel en millisecondes.
   */
  now?: () => number;

  /**
   * Un AbortSignal pour annuler le benchmark.
   */
  signal?: AbortSignal;

  /**
   * Lève une erreur si une tâche échoue (les événements ne fonctionneront pas si cette option est activée).
   */
  throws?: boolean;

  /**
   * Temps de chauffe (millisecondes).
   * @default 100ms
   */
  warmupTime?: number;

  /**
   * Itérations de chauffe.
   * @default 5
   */
  warmupIterations?: number;

  /**
   * Fonction de configuration à exécuter avant chaque tâche de benchmark (cycle).
   */
  setup?: Hook;

  /**
   * Fonction de nettoyage à exécuter après chaque tâche de benchmark (cycle).
   */
  teardown?: Hook;
}

Après l'exécution du cas de test, la structure des informations de sortie est la suivante :

  name                      hz     min     max    mean     p75     p99    p995    p999     rme  samples
· normal sorting  6,526,368.12  0.0001  0.3638  0.0002  0.0002  0.0002  0.0002  0.0004  ±1.41%   652638
ts
export interface TaskResult {
  /*
   * La dernière erreur qui a été levée lors de l'exécution de la tâche.
   */
  error?: unknown;

  /**
   * Le temps total en millisecondes pour exécuter la tâche de benchmark (cycle).
   */
  totalTime: number;

  /**
   * La valeur minimale dans les échantillons.
   */
  min: number;
  /**
   * La valeur maximale dans les échantillons.
   */
  max: number;

  /**
   * Le nombre d'opérations par seconde.
   */
  hz: number;

  /**
   * La durée de chaque opération (ms).
   */
  period: number;

  /**
   * Échantillons de temps pour chaque itération de tâche (ms).
   */
  samples: number[];

  /**
   * Moyenne des échantillons (estimation de la moyenne de la population).
   */
  mean: number;

  /**
   * Variance des échantillons (estimation de la variance de la population).
   */
  variance: number;

  /**
   * Écart-type des échantillons (estimation de l'écart-type de la population).
   */
  sd: number;

  /**
   * Erreur standard de la moyenne (également connue sous le nom d'écart-type de la distribution d'échantillonnage de la moyenne de l'échantillon).
   */
  sem: number;

  /**
   * Degrés de liberté.
   */
  df: number;

  /**
   * Valeur critique des échantillons.
   */
  critical: number;

  /**
   * Marge d'erreur.
   */
  moe: number;

  /**
   * Marge d'erreur relative.
   */
  rme: number;

  /**
   * Déviation absolue médiane.
   */
  mad: number;

  /**
   * Percentile p50/médiane.
   */
  p50: number;

  /**
   * Percentile p75.
   */
  p75: number;

  /**
   * Percentile p99.
   */
  p99: number;

  /**
   * Percentile p995.
   */
  p995: number;

  /**
   * Percentile p999.
   */
  p999: number;
}

bench.skip ​

  • Type : (name: string | Function, fn: BenchFunction, options?: BenchOptions) => void

Vous pouvez utiliser la syntaxe bench.skip pour ignorer l'exécution de certains benchmarks.

ts
import { bench } from 'vitest';

bench.skip('normal sorting', () => {
  const x = [1, 5, 4, 2, 3];
  x.sort((a, b) => {
    return a - b;
  });
});

bench.only ​

  • Type : (name: string | Function, fn: BenchFunction, options?: BenchOptions) => void

Utilisez bench.only pour n'exécuter que certains benchmarks dans une suite donnée. C'est utile lors du débogage.

ts
import { bench } from 'vitest';

bench.only('normal sorting', () => {
  const x = [1, 5, 4, 2, 3];
  x.sort((a, b) => {
    return a - b;
  });
});

bench.todo ​

  • Type : (name: string | Function) => void

Utilisez bench.todo pour marquer des benchmarks à implémenter plus tard.

ts
import { bench } from 'vitest';

bench.todo('unimplemented test');

describe ​

Lorsque vous utilisez test ou bench au niveau supérieur d'un fichier, ils sont inclus dans la suite implicite de celui-ci. En utilisant describe, vous pouvez définir une nouvelle suite dans le contexte actuel, regroupant des tests ou des benchmarks liés ainsi que d'autres suites imbriquées. Une suite vous permet d'organiser vos tests et benchmarks afin que les rapports soient plus clairs.

ts
// basic.spec.ts
// organisation des tests

import { describe, expect, test } from 'vitest';

const person = {
  isActive: true,
  age: 32,
};

describe('person', () => {
  test('person is defined', () => {
    expect(person).toBeDefined();
  });

  test('is active', () => {
    expect(person.isActive).toBeTruthy();
  });

  test('age limit', () => {
    expect(person.age).toBeLessThanOrEqual(32);
  });
});
ts
// basic.bench.ts
// organisation des benchmarks

import { bench, describe } from 'vitest';

describe('sort', () => {
  bench('normal', () => {
    const x = [1, 5, 4, 2, 3];
    x.sort((a, b) => {
      return a - b;
    });
  });

  bench('reverse', () => {
    const x = [1, 5, 4, 2, 3];
    x.reverse().sort((a, b) => {
      return a - b;
    });
  });
});

Vous pouvez également imbriquer des blocs describe si vous avez une hiérarchie de tests ou de benchmarks :

ts
import { describe, expect, test } from 'vitest';

function numberToCurrency(value: number | string) {
  if (typeof value !== 'number') {
    throw new TypeError('Value must be a number');
  }

  return value
    .toFixed(2)
    .toString()
    .replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

describe('numberToCurrency', () => {
  describe('pour un nombre invalide', () => {
    test('qui n\'est pas un nombre doit lever une erreur', () => {
      expect(() => numberToCurrency('abc')).toThrowError();
    });
  });

  describe('pour un nombre valide', () => {
    test('returns the correct currency format', () => {
      expect(numberToCurrency(10000)).toBe('10,000.00');
    });
  });
});

describe.skip ​

  • Alias : suite.skip

Utilisez describe.skip dans une suite pour éviter d'exécuter un bloc describe particulier.

ts
import { assert, describe, test } from 'vitest';

describe.skip('skipped suite', () => {
  test('sqrt', () => {
    // Suite ignorée, pas d'erreur
    assert.equal(Math.sqrt(4), 3);
  });
});

describe.skipIf ​

  • Alias : suite.skipIf

Dans certains cas, vous pouvez être amené à exécuter des suites plusieurs fois dans des environnements différents, et certaines d'entre elles pourraient être spécifiques à l'environnement. Au lieu d'envelopper la suite avec une condition if, vous pouvez utiliser describe.skipIf pour ignorer la suite si la condition est vraie.

ts
import { describe, test } from 'vitest';

const isDev = process.env.NODE_ENV === 'development';

describe.skipIf(isDev)('prod only test suite', () => {
  // cette suite de tests ne s'exécute qu'en production
});

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

describe.runIf ​

  • Alias : suite.runIf

L'opposé de describe.skipIf.

ts
import { assert, describe, test } from 'vitest';

const isDev = process.env.NODE_ENV === 'development';

describe.runIf(isDev)('dev only test suite', () => {
  // cette suite de tests ne s'exécute qu'en développement
});

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

describe.only ​

  • Type : (name: string | Function, fn: TestFunction, options?: number | TestOptions) => void

Utilisez describe.only pour n'exécuter que certaines suites.

ts
import { assert, describe, test } from 'vitest';

// Seule cette suite (et les autres marquées avec only) sont exécutées
describe.only('suite', () => {
  test('sqrt', () => {
    assert.equal(Math.sqrt(4), 3);
  });
});

describe('other suite', () => {
  // ... sera ignorée
});

Il est parfois très utile d'exécuter des tests only dans un certain fichier, en ignorant tous les autres tests de l'ensemble de la suite de tests, afin de ne pas surcharger la sortie.

Pour ce faire, exécutez vitest avec le fichier contenant les tests concernés.

# vitest interesting.test.ts

describe.concurrent ​

  • Alias : suite.concurrent

describe.concurrent exécute toutes les suites et tests internes en parallèle.

ts
import { describe, test } from 'vitest';

// Toutes les suites et tests au sein de cette suite seront exécutés en parallèle
describe.concurrent('suite', () => {
  test('concurrent test 1', async () => {
    /* ... */
  });
  describe('concurrent suite 2', async () => {
    test('concurrent test inner 1', async () => {
      /* ... */
    });
    test('concurrent test inner 2', async () => {
      /* ... */
    });
  });
  test.concurrent('concurrent test 3', async () => {
    /* ... */
  });
});

.skip, .only et .todo fonctionnent avec les suites concurrentes. Toutes les combinaisons suivantes sont valides :

ts
describe.concurrent(/* ... */);
describe.skip.concurrent(/* ... */); // ou describe.concurrent.skip(/* ... */)
describe.only.concurrent(/* ... */); // ou describe.concurrent.only(/* ... */)
describe.todo.concurrent(/* ... */); // ou describe.concurrent.todo(/* ... */)

Lors de l'exécution de tests concurrents, les instantanés (Snapshots) et les assertions doivent utiliser expect du Contexte de Test local pour s'assurer que le bon test est détecté.

ts
describe.concurrent('suite', () => {
  test('concurrent test 1', async ({ expect }) => {
    expect(foo).toMatchSnapshot();
  });
  test('concurrent test 2', async ({ expect }) => {
    expect(foo).toMatchSnapshot();
  });
});

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

describe.sequential ​

  • Alias : suite.sequential

describe.sequential dans une suite marque chaque test comme séquentiel. C'est utile si vous voulez exécuter des tests en séquence au sein de describe.concurrent ou avec l'option de commande --sequence.concurrent.

ts
import { describe, test } from 'vitest';

describe.concurrent('suite', () => {
  test('concurrent test 1', async () => {
    /* ... */
  });
  test('concurrent test 2', async () => {
    /* ... */
  });

  describe.sequential('', () => {
    test('sequential test 1', async () => {
      /* ... */
    });
    test('sequential test 2', async () => {
      /* ... */
    });
  });
});

describe.shuffle ​

  • Alias : suite.shuffle

Vitest offre un moyen d'exécuter tous les tests dans un ordre aléatoire via l'option CLI --sequence.shuffle ou l'option de configuration sequence.shuffle. Si vous souhaitez qu'une partie seulement de votre suite de tests exécute les tests dans un ordre aléatoire, vous pouvez la marquer avec cette option.

ts
import { describe, test } from 'vitest';

// ou describe('suite', { shuffle: true }, ...)
describe.shuffle('suite', () => {
  test('random test 1', async () => {
    /* ... */
  });
  test('random test 2', async () => {
    /* ... */
  });
  test('random test 3', async () => {
    /* ... */
  });

  // `shuffle` est hérité
  describe('still random', () => {
    test('random 4.1', async () => {
      /* ... */
    });
    test('random 4.2', async () => {
      /* ... */
    });
  });

  // désactiver l'ordre aléatoire à l'intérieur
  describe('not random', { shuffle: false }, () => {
    test('in order 5.1', async () => {
      /* ... */
    });
    test('in order 5.2', async () => {
      /* ... */
    });
  });
});
// l'ordre dépend de l'option sequence.seed dans la configuration (Date.now() par défaut)

.skip, .only et .todo fonctionnent avec les suites aléatoires.

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

describe.todo ​

  • Alias : suite.todo

Utilisez describe.todo pour marquer des suites à implémenter plus tard. Ces suites apparaîtront dans le rapport, vous indiquant ainsi le nombre de tests qu'il vous reste à implémenter.

ts
// Une entrée sera affichée dans le rapport pour cette suite
describe.todo('unimplemented suite');

describe.each ​

  • Alias : suite.each

TIP

Bien que describe.each soit fourni pour la compatibilité Jest, Vitest dispose également de describe.for qui simplifie les types d'arguments et s'aligne avec test.for.

Utilisez describe.each si plusieurs tests dépendent des mêmes données.

ts
import { describe, expect, test } from 'vitest';

describe.each([
  { a: 1, b: 1, expected: 2 },
  { a: 1, b: 2, expected: 3 },
  { a: 2, b: 1, expected: 3 },
])('description de l\'objet add($a, $b)', ({ a, b, expected }) => {
  test(`returns ${expected}`, () => {
    expect(a + b).toBe(expected);
  });

  test(`la valeur retournée ne doit pas être supérieure à ${expected}`, () => {
    expect(a + b).not.toBeGreaterThan(expected);
  });

  test(`la valeur retournée ne doit pas être inférieure à ${expected}`, () => {
    expect(a + b).not.toBeLessThan(expected);
  });
});

À partir de Vitest 0.25.3, vous pouvez également utiliser une table de chaînes de caractères de modèle.

  • La première ligne doit contenir les noms de colonnes, séparés par | ;
  • Une ou plusieurs lignes de données suivantes fournies sous forme d'expressions littérales de modèle utilisant la syntaxe ${value}.
ts
import { describe, expect, test } from 'vitest';

describe.each`
  a             | b      | expected
  ${1}          | ${1}   | ${2}
  ${'a'}        | ${'b'} | ${'ab'}
  ${[]}         | ${'b'} | ${'b'}
  ${{}}         | ${'b'} | ${'[object Object]b'}
  ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
`('description de la chaîne de modèle add($a, $b)', ({ a, b, expected }) => {
  test(`returns ${expected}`, () => {
    expect(a + b).toBe(expected);
  });
});

WARNING

Vous ne pouvez pas utiliser cette syntaxe lorsque vous utilisez Vitest comme vérificateur de type.

describe.for ​

  • Alias : suite.for

La différence avec describe.each réside dans la manière dont les arguments de type tableau sont fournis. Les autres types d'arguments non-tableau (y compris l'utilisation de chaînes de caractères de modèle) fonctionnent exactement de la même manière.

ts
// `each` déstructure les arguments de type tableau
describe.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => { 
  test('test', () => {
    expect(a + b).toBe(expected);
  });
});

// `for` ne déstructure pas les arguments de type tableau
describe.for([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add(%i, %i) -> %i', ([a, b, expected]) => { 
  test('test', () => {
    expect(a + b).toBe(expected);
  });
});

Configuration et Nettoyage ​

Ces fonctions vous permettent de vous intégrer au cycle de vie des tests afin d'éviter de répéter le code de configuration et de nettoyage. Elles s'appliquent au contexte actuel : le fichier si elles sont utilisées au niveau supérieur ou la suite actuelle si elles sont à l'intérieur d'un bloc describe. Ces hooks ne sont pas appelés lorsque vous exécutez Vitest en tant que vérificateur de type.

beforeEach ​

  • Type : beforeEach(fn: () => Awaitable<void>, timeout?: number)

Enregistre une fonction de rappel qui sera appelée avant l'exécution de chacun des tests dans le contexte actuel. Si la fonction renvoie une promesse, Vitest attend que la promesse soit résolue avant d'exécuter le test.

Optionnellement, vous pouvez spécifier un délai d'attente (en millisecondes) définissant la durée maximale avant l'arrêt. La valeur par défaut est de 5 secondes.

ts
import { beforeEach } from 'vitest';

beforeEach(async () => {
  // Effacer les mocks et ajouter des données de test avant chaque exécution de test
  await stopMocking();
  await addUser({ name: 'John' });
});

Ici, beforeEach garantit que les données utilisateur sont ajoutées pour chaque test.

beforeEach accepte également une fonction de nettoyage optionnelle (équivalente à afterEach).

ts
import { beforeEach } from 'vitest';

beforeEach(async () => {
  // appelé une fois avant chaque exécution de test
  await prepareSomething();

  // fonction de nettoyage, appelée une fois après chaque exécution de test
  return async () => {
    await resetSomething();
  };
});

afterEach ​

  • Type : afterEach(fn: () => Awaitable<void>, timeout?: number)

Enregistre une fonction de rappel qui sera appelée après que chacun des tests dans le contexte actuel soit terminé. Si la fonction renvoie une promesse, Vitest attend que la promesse soit résolue avant de continuer.

Optionnellement, vous pouvez fournir un délai d'attente (en millisecondes) pour spécifier combien de temps attendre avant de terminer. La valeur par défaut est de 5 secondes.

ts
import { afterEach } from 'vitest';

afterEach(async () => {
  await clearTestingData(); // effacer les données de test après chaque exécution de test
});

Ici, afterEach garantit que les données de test sont effacées après chaque exécution de test.

TIP

Vitest 1.3.0 a ajouté le hook onTestFinished. Vous pouvez l'appeler pendant l'exécution du test pour nettoyer tout état une fois le test terminé.

beforeAll ​

  • Type : beforeAll(fn: () => Awaitable<void>, timeout?: number)

Enregistre une fonction de rappel qui sera appelée une fois avant de commencer l'exécution de tous les tests dans le contexte actuel. Si la fonction renvoie une promesse, Vitest attend que la promesse soit résolue avant d'exécuter les tests.

Optionnellement, vous pouvez fournir un délai d'attente (en millisecondes) pour spécifier combien de temps attendre avant de terminer. La valeur par défaut est de 5 secondes.

ts
import { beforeAll } from 'vitest';

beforeAll(async () => {
  await startMocking(); // appelé une fois avant l'exécution de tous les tests
});

Ici, beforeAll garantit que les données de mock sont configurées avant l'exécution des tests.

beforeAll accepte également une fonction de nettoyage optionnelle (équivalente à afterAll).

ts
import { beforeAll } from 'vitest';

beforeAll(async () => {
  // appelé une fois avant l'exécution de tous les tests
  await startMocking();

  // fonction de nettoyage, appelée une fois après l'exécution de tous les tests
  return async () => {
    await stopMocking();
  };
});

afterAll ​

  • Type : afterAll(fn: () => Awaitable<void>, timeout?: number)

Enregistre une fonction de rappel qui sera appelée une fois après l'exécution de tous les tests dans le contexte actuel. Si la fonction renvoie une promesse, Vitest attend que la promesse soit résolue avant de continuer.

Optionnellement, vous pouvez fournir un délai d'attente (en millisecondes) pour spécifier combien de temps attendre avant de terminer. La valeur par défaut est de 5 secondes.

ts
import { afterAll } from 'vitest';

afterAll(async () => {
  await stopMocking(); // cette méthode est appelée après l'exécution de tous les tests
});

Ici, afterAll garantit que la méthode stopMocking est appelée après l'exécution de tous les tests.

Hooks de Test ​

Vitest fournit quelques hooks que vous pouvez appeler pendant l'exécution du test pour nettoyer l'état une fois le test terminé.

WARNING

Ces hooks lèveront une erreur s'ils sont appelés en dehors du corps du test.

onTestFinished ​

Ce hook est toujours appelé une fois le test terminé. Il est appelé après les hooks afterEach car ils peuvent influencer le résultat du test. Il reçoit un objet ExtendedContext similaire à ceux de beforeEach et afterEach.

ts
import { onTestFinished, test } from 'vitest';

test('performs a query', () => {
  const db = connectDb();
  onTestFinished(() => db.close());
  db.query('SELECT * FROM users');
});

WARNING

Si vous exécutez des tests en parallèle, vous devez toujours utiliser le hook onTestFinished du contexte de test, car Vitest ne gère pas les tests concurrents dans les hooks globaux :

ts
import { test } from 'vitest';

test.concurrent('performs a query', ({ onTestFinished }) => {
  const db = connectDb();
  onTestFinished(() => db.close());
  db.query('SELECT * FROM users');
});

Ce hook est particulièrement utile lors de la création de logique réutilisable :

ts
// cela peut être dans un fichier séparé
function getTestDb() {
  const db = connectMockedDb();
  onTestFinished(() => db.close());
  return db;
}

test('performs a user query', async () => {
  const db = getTestDb();
  expect(await db.query('SELECT * from users').perform()).toEqual([]);
});

test('performs an organization query', async () => {
  const db = getTestDb();
  expect(await db.query('SELECT * from organizations').perform()).toEqual([]);
});

TIP

Ce hook est toujours appelé dans l'ordre inverse et n'est pas affecté par l'option sequence.hooks.

onTestFailed ​

Ce hook est appelé uniquement après l'échec du test. Il est appelé après les hooks afterEach car ils peuvent influencer le résultat du test. Il reçoit un objet ExtendedContext similaire à ceux de beforeEach et afterEach. Ce hook est utile pour le débogage.

ts
import { onTestFailed, test } from 'vitest';

test('performs a query', () => {
  const db = connectDb();
  onTestFailed(({ task }) => {
    console.log(task.result.errors);
  });
  db.query('SELECT * FROM users');
});

WARNING

Si vous exécutez des tests en parallèle, vous devez toujours utiliser le hook onTestFailed du contexte de test, car Vitest ne gère pas les tests concurrents dans les hooks globaux :

ts
import { test } from 'vitest';

test.concurrent('performs a query', ({ onTestFailed }) => {
  const db = connectDb();
  onTestFailed(({ task }) => {
    console.log(task.result.errors);
  });
  db.query('SELECT * FROM users');
});
Pager
Page précédenteConfiguration de Vitest
Page suivanteFonctions Mocks

Publié sous la licence MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/api/

Publié sous la licence MIT.

Copyright (c) 2021-Present Vitest Team