Skip to content
Vitest 3
Main Navigation Guida & APIConfigurazioneModalità BrowserAPI avanzata
3.2.0
2.1.9
1.6.1
0.34.6

Italiano

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

Italiano

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

Aspetto

Sidebar Navigation

Introduzione

Perché Vitest

Per Iniziare

Caratteristiche

Configurazione di Vitest

API

Riferimento API di test

Funzioni Mock

Vi

expect

expectTypeOf

assert

assertType

Guida

Interfaccia a Riga di Comando

Filtro dei Test

Progetti di Test

Reporter

Copertura

Snapshot

Mocking

Parallelismo

Tipi di Test

Vitest UI

Test nel Codice Sorgente

Contesto di Test

Annotazioni dei Test

Ambiente di Test

Estensione dei Matcher

Integrazioni IDE

Debugging

Errori Comuni

Guida alla Migrazione

Migrazione a Vitest 3.0

Migrazione da Jest

Prestazioni

Profilazione delle prestazioni dei test

Ottimizzare le Prestazioni

Modalità Browser

API Avanzate

Confronto con Altri Test Runner

In questa pagina

Riferimento API di test ​

I seguenti tipi sono utilizzati nelle firme dei tipi qui sotto.

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

interface TestOptions {
  /**
   * Il test fallirà se l'esecuzione supera il tempo limite specificato.
   */
  timeout?: number;
  /**
   * Riprova il test un numero specifico di volte in caso di fallimento.
   *
   * @default 0
   */
  retry?: number;
  /**
   * Ripete lo stesso test più volte, anche in caso di fallimento.
   * Se l'opzione "retry" è attiva e il test fallisce, ogni tentativo verrà utilizzato in ogni ciclo di ripetizione.
   * Utile per diagnosticare fallimenti intermittenti.
   *
   * @default 0
   */
  repeats?: number;
}

Quando una funzione di test restituisce una promise, il runner attenderà che questa sia risolta per raccogliere le aspettative asincrone. Se la promise viene rifiutata, il test fallirà.

TIP

In Jest, TestFunction può anche essere di tipo (done: DoneCallback) => void. Se si usa questa forma, il test non sarà concluso finché non viene chiamata done. Puoi ottenere lo stesso risultato usando una funzione async; per maggiori dettagli, consulta la sezione Callback Done della guida alla migrazione.

È possibile definire le opzioni concatenando i metodi a una funzione di test:

ts
import { test } from 'vitest';

test.skip('skipped test', () => {
  // logica che attualmente fallisce
});

test.concurrent.skip('skipped concurrent test', () => {
  // logica che attualmente fallisce
});

Tuttavia, è anche possibile fornire un oggetto di opzioni come secondo argomento:

ts
import { test } from 'vitest';

test('skipped test', { skip: true }, () => {
  // logica che attualmente fallisce
});

test('skipped concurrent test', { skip: true, concurrent: true }, () => {
  // logica che attualmente fallisce
});

Entrambe le sintassi funzionano esattamente allo stesso modo. La scelta tra l'una o l'altra è puramente stilistica.

Si noti che se si fornisce il timeout come ultimo argomento, non è più possibile utilizzare l'oggetto opzioni:

ts
import { test } from 'vitest';

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

// ❌ Questo non funziona
test(
  'heavy test',
  { skip: true },
  () => {
    // ...
  },
  10_000
);

Tuttavia, è possibile fornire un timeout all'interno dell'oggetto opzioni:

ts
import { test } from 'vitest';

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

test ​

  • Alias: it

test definisce un insieme di aspettative correlate. Accetta il nome del test e una funzione che contiene le aspettative da verificare.

Opzionalmente, è possibile fornire un timeout (in millisecondi) per specificare il tempo massimo di attesa prima della terminazione. Il valore predefinito è 5 secondi e può essere configurato globalmente tramite testTimeout.

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

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

test.extend ​

  • Alias: it.extend

Utilizzare test.extend per estendere il contesto del test con fixture personalizzate. Questo restituirà un nuovo test, che sarà a sua volta estendibile, consentendo di comporre ulteriori fixture o di sovrascrivere quelle esistenti estendendolo secondo necessità. Per maggiori informazioni, consultare Estendi Contesto di Test.

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

Se si desidera saltare l'esecuzione di determinati test, ma non si vuole eliminare il codice per qualsiasi motivo, è possibile utilizzare test.skip per evitarne l'esecuzione.

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

test.skip('skipped test', () => {
  // Test saltato, nessun errore.
  assert.equal(Math.sqrt(4), 3);
});

È anche possibile saltare un test chiamando skip sul suo contesto dinamicamente:

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

test('skipped test', context => {
  context.skip();
  // Test saltato, nessun errore.
  assert.equal(Math.sqrt(4), 3);
});

A partire da Vitest 3.1, se la condizione è sconosciuta, è possibile fornirla al metodo skip come primo argomento:

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

test('skipped test', context => {
  context.skip(Math.random() < 0.5, 'optional message');
  // Test saltato, nessun errore.
  assert.equal(Math.sqrt(4), 3);
});

test.skipIf ​

  • Alias: it.skipIf

In alcuni casi, si potrebbero eseguire i test più volte con ambienti diversi, e alcuni di essi potrebbero essere specifici dell'ambiente. Invece di racchiudere il codice del test con un if, è possibile utilizzare test.skipIf per saltare il test ogni volta che la condizione specificata è vera.

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

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

test.skipIf(isDev)('prod only test', () => {
  // Questo test viene eseguito solo in produzione.
});

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

test.runIf ​

  • Alias: it.runIf

Opposto di test.skipIf.

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

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

test.runIf(isDev)('dev only test', () => {
  // Questo test viene eseguito solo in sviluppo.
});

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

test.only ​

  • Alias: it.only

Utilizzare test.only per eseguire solo determinati test all'interno di una data suite. Questo è utile durante il debug.

Opzionalmente, è possibile fornire un timeout (in millisecondi) per specificare il tempo massimo di attesa prima della terminazione. Il valore predefinito è 5 secondi e può essere configurato globalmente con testTimeout.

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

test.only('test', () => {
  // Solo questo test (e altri marcati con `only`) vengono eseguiti.
  assert.equal(Math.sqrt(4), 2);
});

A volte è molto utile eseguire solo i test marcati con only in un determinato file, ignorando tutti gli altri test dell'intera suite, che potrebbero inquinare l'output.

Per fare ciò, esegui vitest con il file specifico contenente i test in questione:

# vitest interesting.test.ts

test.concurrent ​

  • Alias: it.concurrent

test.concurrent marca i test consecutivi per essere eseguiti in parallelo. Accetta il nome del test, una funzione asincrona con i test da raccogliere e un timeout opzionale (in millisecondi).

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

// I due test marcati con `concurrent` verranno eseguiti in parallelo.
describe('suite', () => {
  test('serial test', async () => {
    /* ... */
  });
  test.concurrent('concurrent test 1', async () => {
    /* ... */
  });
  test.concurrent('concurrent test 2', async () => {
    /* ... */
  });
});

test.skip, test.only e test.todo funzionano con i test concorrenti. Tutte le seguenti combinazioni sono valide:

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

Quando si eseguono test concorrenti, gli Snapshot e le Asserzioni devono utilizzare expect dal Contesto di Test locale per garantire che il test corretto venga rilevato.

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

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

test.sequential ​

  • Alias: it.sequential

test.sequential marca un test come sequenziale. Questo è utile se si desidera eseguire i test in sequenza all'interno di describe.concurrent o con l'opzione da riga di comando --sequence.concurrent.

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

// con l'opzione di configurazione { 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 () => {
  /* ... */
});

// all'interno di una suite concorrente.
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

Utilizzare test.todo per creare test stub da implementare in seguito. Nel report verrà mostrata una voce per questi test, in modo da sapere quanti test devono ancora essere implementati.

ts
// Nel report verrà mostrata una voce per questo test.
test.todo('unimplemented test');

test.fails ​

  • Alias: it.fails

Utilizzare test.fails per indicare esplicitamente che un'asserzione fallirà.

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

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

test.each ​

  • Alias: it.each

TIP

Mentre test.each è fornito per la compatibilità con Jest, Vitest dispone anche di test.for con una funzionalità aggiuntiva per integrare TestContext.

Usa test.each quando devi eseguire lo stesso test con variabili diverse. È possibile iniettare parametri con la formattazione printf nel nome del test, seguendo l'ordine dei parametri della funzione di test.

  • %s: stringa
  • %d: numero
  • %i: intero
  • %f: valore in virgola mobile
  • %j: json
  • %o: oggetto
  • %#: indice basato su 0 del caso di test
  • %$: indice basato su 1 del caso di test
  • %%: singolo segno di percentuale ('%')
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);
});

// questo restituirà:
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3

È anche possibile accedere alle proprietà degli oggetti e agli elementi degli array con il prefisso $:

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);
});

// questo restituirà:
// ✓ 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);
});

// questo restituirà:
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3

È anche possibile accedere agli attributi degli oggetti con ., se si utilizzano oggetti come argomenti:

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);
});

// questo restituirà:
// ✓ add(1, b) -> 1b
// ✓ add(2, b) -> 2b
// ✓ add(3, b) -> 3b

A partire da Vitest 0.25.3, puoi anche usare la tabella di stringhe template.

  • La prima riga dovrebbe contenere i nomi delle colonne, separati da |;
  • Una o più righe successive di dati fornite come espressioni letterali template utilizzando la sintassi ${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 elabora i $values con il metodo format di Chai. Se il valore è troppo troncato, puoi aumentare chaiConfig.truncateThreshold nel tuo file di configurazione.

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

test.for ​

  • Alias: it.for

Alternativa a test.each per fornire TestContext.

La differenza rispetto a test.each risiede nel modo in cui gli array vengono forniti negli argomenti. Gli argomenti non-array di test.for (incluso l'uso di stringhe template) funzionano esattamente come per test.each.

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

// `for` non espande gli array (si notino le parentesi quadre attorno agli argomenti)
test.for([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add(%i, %i) -> %i', ([a, b, expected]) => { 
  expect(a + b).toBe(expected);
});

Il secondo argomento è TestContext e può essere utilizzato per snapshot concorrenti, ad esempio:

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

bench ​

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

bench definisce un benchmark. In termini di Vitest, un benchmark è una funzione che definisce una serie di operazioni. Vitest esegue questa funzione più volte per visualizzare diversi risultati di performance.

Vitest utilizza la libreria tinybench "sotto il cofano", ereditando tutte le sue opzioni che possono essere utilizzate come terzo argomento.

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 {
  /**
   * Tempo massimo (in millisecondi) per l'esecuzione di un'attività di benchmark.
   * @default 500
   */
  time?: number;

  /**
   * Numero minimo di volte che un'attività dovrebbe essere eseguita, anche se l'opzione `time` è terminata.
   * @default 10
   */
  iterations?: number;

  /**
   * Funzione per ottenere il timestamp corrente in millisecondi.
   */
  now?: () => number;

  /**
   * Un `AbortSignal` per abortire il benchmark.
   */
  signal?: AbortSignal;

  /**
   * Lancia un errore se un'attività fallisce (gli eventi non funzioneranno se `true`).
   */
  throws?: boolean;

  /**
   * Tempo di riscaldamento (in millisecondi).
   * @default 100ms
   */
  warmupTime?: number;

  /**
   * Iterazioni di riscaldamento.
   * @default 5
   */
  warmupIterations?: number;

  /**
   * Funzione di setup da eseguire prima di ogni attività di benchmark (ciclo).
   */
  setup?: Hook;

  /**
   * Funzione di teardown da eseguire dopo ogni attività di benchmark (ciclo).
   */
  teardown?: Hook;
}

Dopo l'esecuzione del caso di test, le informazioni sulla struttura dell'output sono le seguenti:

  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 {
  /*
   * L'ultimo errore che è stato lanciato durante l'esecuzione dell'attività.
   */
  error?: unknown;

  /**
   * Il tempo totale (in millisecondi) impiegato per eseguire l'attività di benchmark (ciclo).
   */
  totalTime: number;

  /**
   * Il valore minimo nei campioni.
   */
  min: number;
  /**
   * Il valore massimo nei campioni.
   */
  max: number;

  /**
   * Il numero di operazioni al secondo (Hertz).
   */
  hz: number;

  /**
   * Quanto tempo impiega ogni operazione (in millisecondi).
   */
  period: number;

  /**
   * Campioni di tempo di ogni iterazione dell'attività (in millisecondi).
   */
  samples: number[];

  /**
   * Media dei campioni (stima della media della popolazione).
   */
  mean: number;

  /**
   * Varianza dei campioni (stima della varianza della popolazione).
   */
  variance: number;

  /**
   * Deviazione standard dei campioni (stima della deviazione standard della popolazione).
   */
  sd: number;

  /**
   * Errore standard della media (ovvero la deviazione standard della distribuzione campionaria della media campionaria).
   */
  sem: number;

  /**
   * Gradi di libertà.
   */
  df: number;

  /**
   * Valore critico dei campioni.
   */
  critical: number;

  /**
   * Margine di errore.
   */
  moe: number;

  /**
   * Margine di errore relativo.
   */
  rme: number;

  /**
   * Deviazione assoluta mediana.
   */
  mad: number;

  /**
   * Percentile p50/mediana.
   */
  p50: number;

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

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

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

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

bench.skip ​

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

È possibile utilizzare la sintassi bench.skip per saltare l'esecuzione di determinati benchmark.

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 ​

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

Utilizzare bench.only per eseguire solo determinati benchmark all'interno di una data suite. Questo è utile durante il debug.

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 ​

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

Utilizzare bench.todo per creare benchmark stub da implementare in seguito.

ts
import { bench } from 'vitest';

bench.todo('unimplemented test');

Descrivi ​

Quando si utilizzano test o bench al livello superiore di un file, questi vengono raccolti come parte della suite implicita. Utilizzando describe, è possibile definire una nuova suite nel contesto corrente, come un insieme di test o benchmark correlati e altre suite annidate. Una suite consente di organizzare i test e i benchmark in modo che i report siano più chiari.

ts
// basic.spec.ts
// organizzazione dei test.

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
// organizzazione dei benchmark.

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;
    });
  });
});

È anche possibile annidare blocchi describe se si dispone di una gerarchia di test o benchmark:

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('given an invalid number', () => {
    test('composed of non-numbers to throw error', () => {
      expect(() => numberToCurrency('abc')).toThrowError();
    });
  });

  describe('given a valid number', () => {
    test('returns the correct currency format', () => {
      expect(numberToCurrency(10000)).toBe('10,000.00');
    });
  });
});

describe.skip ​

  • Alias: suite.skip

Utilizzare describe.skip in una suite per evitare di eseguire un particolare blocco describe.

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

describe.skip('skipped suite', () => {
  test('sqrt', () => {
    // Suite saltata, nessun errore.
    assert.equal(Math.sqrt(4), 3);
  });
});

describe.skipIf ​

  • Alias: suite.skipIf

In alcuni casi, si potrebbero eseguire le suite più volte con ambienti diversi, e alcune di esse potrebbero essere specifiche dell'ambiente. Invece di racchiudere la suite con un if, è possibile utilizzare describe.skipIf per saltare la suite ogni volta che la condizione specificata è vera.

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

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

describe.skipIf(isDev)('prod only test suite', () => {
  // Questa suite di test viene eseguita solo in produzione.
});

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

describe.runIf ​

  • Alias: suite.runIf

Opposto di describe.skipIf.

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

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

describe.runIf(isDev)('dev only test suite', () => {
  // Questa suite di test viene eseguita solo in sviluppo.
});

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

describe.only ​

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

Utilizzare describe.only per eseguire solo determinate suite.

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

// Solo questa suite (e altre marcate con `only`) vengono eseguite.
describe.only('suite', () => {
  test('sqrt', () => {
    assert.equal(Math.sqrt(4), 3);
  });
});

describe('other suite', () => {
  // ... verrà saltata.
});

A volte è molto utile eseguire test only in un certo file, ignorando tutti gli altri test dell'intera suite di test, che inquinano l'output.

Per fare ciò, esegui vitest con il file specifico contenente i test in questione:

# vitest interesting.test.ts

describe.concurrent ​

  • Alias: suite.concurrent

describe.concurrent esegue tutte le suite e i test interni in parallelo.

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

// Tutte le suite e i test all'interno di questa suite verranno eseguiti in parallelo.
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 e .todo funzionano con le suite concorrenti. Tutte le seguenti combinazioni sono valide:

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

Quando si eseguono test concorrenti, gli Snapshot e le Asserzioni devono utilizzare expect dal Contesto di Test locale per garantire che il test corretto venga rilevato.

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

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

describe.sequential ​

  • Alias: suite.sequential

describe.sequential in una suite marca ogni test come sequenziale. Questo è utile se si desidera eseguire i test in sequenza all'interno di describe.concurrent o con l'opzione da riga di comando --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 modo per eseguire tutti i test in ordine casuale tramite il flag CLI --sequence.shuffle o l'opzione di configurazione sequence.shuffle. Tuttavia, se si desidera che solo una parte della suite di test esegua i test in ordine casuale, è possibile marcarla con questo flag.

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

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

  // `shuffle` è ereditato
  describe('still random', () => {
    test('random 4.1', async () => {
      /* ... */
    });
    test('random 4.2', async () => {
      /* ... */
    });
  });

  // disabilita lo `shuffle` all'interno
  describe('not random', { shuffle: false }, () => {
    test('in order 5.1', async () => {
      /* ... */
    });
    test('in order 5.2', async () => {
      /* ... */
    });
  });
});
// l'ordine dipende dall'opzione `sequence.seed` nella configurazione (`Date.now()` per impostazione predefinita).

.skip, .only e .todo funzionano con le suite casuali.

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

describe.todo ​

  • Alias: suite.todo

Utilizzare describe.todo per creare suite stub da implementare in seguito. Nel report verrà mostrata una voce per queste suite, in modo da sapere quante suite devono ancora essere implementate.

ts
// Nel report verrà mostrata una voce per questa suite.
describe.todo('unimplemented suite');

describe.each ​

  • Alias: suite.each

TIP

Mentre describe.each è fornito per la compatibilità con Jest, Vitest dispone anche di describe.for, che semplifica i tipi di argomento e si allinea con test.for.

Utilizzare describe.each se si dispone di più di un test che dipende dagli stessi dati.

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 },
])('describe object add($a, $b)', ({ a, b, expected }) => {
  test(`returns ${expected}`, () => {
    expect(a + b).toBe(expected);
  });

  test(`returned value not be greater than ${expected}`, () => {
    expect(a + b).not.toBeGreaterThan(expected);
  });

  test(`returned value not be less than ${expected}`, () => {
    expect(a + b).not.toBeLessThan(expected);
  });
});

A partire da Vitest 0.25.3, puoi anche usare la tabella di stringhe template.

  • La prima riga dovrebbe contenere i nomi delle colonne, separati da |;
  • Una o più righe successive di dati fornite come espressioni letterali template utilizzando la sintassi ${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'}
`('describe template string add($a, $b)', ({ a, b, expected }) => {
  test(`returns ${expected}`, () => {
    expect(a + b).toBe(expected);
  });
});

WARNING

Non puoi usare questa sintassi quando usi Vitest come controllore di tipi.

describe.for ​

  • Alias: suite.for

La differenza rispetto a describe.each risiede nel modo in cui il caso array viene fornito negli argomenti. Gli altri casi non-array (incluso l'uso di stringhe template) funzionano esattamente allo stesso modo.

ts
// `each` espande il caso array
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` non espande il caso array
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);
  });
});

Setup e Teardown ​

Queste funzioni consentono di agganciarsi al ciclo di vita dei test per evitare la ripetizione del codice di setup e teardown. Si applicano al contesto corrente: il file, se utilizzate al livello superiore, o la suite corrente, se si trovano all'interno di un blocco describe. Questi hook non vengono chiamati quando si esegue Vitest come controllore di tipi.

beforeEach ​

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

Registra una callback da chiamare prima dell'esecuzione di ciascun test nel contesto corrente. Se la funzione restituisce una promise, Vitest attende che la promise si risolva prima di eseguire il test.

Opzionalmente, è possibile passare un timeout (in millisecondi) che definisce il tempo massimo di attesa prima della terminazione. Il valore predefinito è 5 secondi.

ts
import { beforeEach } from 'vitest';

beforeEach(async () => {
  // Cancella i mock e aggiungi alcuni dati di test prima di ogni esecuzione del test.
  await stopMocking();
  await addUser({ name: 'John' });
});

Qui, beforeEach assicura che l'utente venga aggiunto per ogni test.

beforeEach accetta anche una funzione di pulizia opzionale (equivalente a afterEach).

ts
import { beforeEach } from 'vitest';

beforeEach(async () => {
  // Chiamato una volta prima di ogni esecuzione del test.
  await prepareSomething();

  // Funzione di pulizia, chiamata una volta dopo ogni esecuzione del test.
  return async () => {
    await resetSomething();
  };
});

afterEach ​

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

Registra una callback da chiamare dopo che ciascuno dei test nel contesto corrente è stato completato. Se la funzione restituisce una promise, Vitest attende che la promise si risolva prima di continuare.

Opzionalmente, è possibile fornire un timeout (in millisecondi) per specificare il tempo massimo di attesa prima della terminazione. Il valore predefinito è 5 secondi.

ts
import { afterEach } from 'vitest';

afterEach(async () => {
  await clearTestingData(); // Cancella i dati di test dopo ogni esecuzione del test.
});

Qui, afterEach assicura che i dati di test vengano cancellati dopo ogni esecuzione del test.

TIP

Vitest 1.3.0 ha aggiunto l'hook onTestFinished. È possibile chiamarlo durante l'esecuzione del test per pulire qualsiasi stato dopo che il test è terminato.

beforeAll ​

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

Registra una callback da chiamare una volta prima di iniziare l'esecuzione di tutti i test nel contesto corrente. Se la funzione restituisce una promise, Vitest attende che la promise si risolva prima di eseguire i test.

Opzionalmente, è possibile fornire un timeout (in millisecondi) per specificare il tempo massimo di attesa prima della terminazione. Il valore predefinito è 5 secondi.

ts
import { beforeAll } from 'vitest';

beforeAll(async () => {
  await startMocking(); // Chiamato una volta prima di tutti i test.
});

Qui beforeAll assicura che i dati mock siano impostati prima dell'esecuzione dei test.

beforeAll accetta anche una funzione di pulizia opzionale (equivalente a afterAll).

ts
import { beforeAll } from 'vitest';

beforeAll(async () => {
  // Chiamato una volta prima di tutti i test.
  await startMocking();

  // Funzione di pulizia, chiamata una volta dopo tutti i test.
  return async () => {
    await stopMocking();
  };
});

afterAll ​

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

Registra una callback da chiamare una volta dopo che tutti i test sono stati eseguiti nel contesto corrente. Se la funzione restituisce una promise, Vitest attende che la promise si risolva prima di continuare.

Opzionalmente, è possibile fornire un timeout (in millisecondi) per specificare il tempo massimo di attesa prima della terminazione. Il valore predefinito è 5 secondi.

ts
import { afterAll } from 'vitest';

afterAll(async () => {
  await stopMocking(); // Questo metodo viene chiamato dopo l'esecuzione di tutti i test.
});

Qui afterAll assicura che il metodo stopMocking venga chiamato dopo l'esecuzione di tutti i test.

Hook di Test ​

Vitest fornisce alcuni hook che è possibile chiamare durante l'esecuzione del test per pulire lo stato una volta che il test è terminato.

WARNING

Questi hook lanceranno un errore se vengono chiamati al di fuori del corpo del test.

onTestFinished ​

Questo hook viene sempre chiamato dopo che il test è terminato. Viene chiamato dopo gli hook afterEach, poiché possono influenzare il risultato del test. Riceve un oggetto ExtendedContext come beforeEach e afterEach.

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

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

WARNING

Se si stanno eseguendo test in parallelo, si dovrebbe sempre utilizzare l'hook onTestFinished dal contesto del test, poiché Vitest non tiene traccia dei test concorrenti negli hook globali:

ts
import { test } from 'vitest';

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

Questo hook è particolarmente utile quando si crea una logica riutilizzabile:

ts
// Questo può essere in un file separato.
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

Questo hook viene sempre chiamato in ordine inverso e non è influenzato dall'opzione sequence.hooks.

onTestFailed ​

Questo hook viene chiamato solo dopo che il test è fallito. Viene chiamato dopo gli hook afterEach, poiché possono influenzare il risultato del test. Riceve un oggetto ExtendedContext come beforeEach e afterEach. Questo hook è utile per il debug.

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

Se si stanno eseguendo test in parallelo, si dovrebbe sempre utilizzare l'hook onTestFailed dal contesto del test, poiché Vitest non tiene traccia dei test concorrenti negli hook globali:

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
Pagina precedenteConfigurazione di Vitest
Pagina successivaFunzioni Mock

Rilasciato sotto la licenza MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/api/

Rilasciato sotto la licenza MIT.

Copyright (c) 2021-Present Vitest Team