Riferimento API Test
I seguenti tipi sono utilizzati nelle firme dei tipi sottostanti
type Awaitable<T> = T | PromiseLike<T>;
type TestFunction = () => Awaitable<void>;
interface TestOptions {
/**
* Il test fallirà se impiega troppo tempo per essere eseguito
*/
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 se fallisce ogni volta.
* Se hai l'opzione "retry" e il test fallisce, utilizzerà ogni tentativo in ogni ciclo.
* Utile per il debug di fallimenti casuali.
*
* @default 0
*/
repeats?: number;
}Quando una funzione di test restituisce una promise, il runner attenderà che venga 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 viene utilizzata questa forma, il test non sarà considerato concluso finché non viene chiamato done. Puoi ottenere lo stesso effetto usando una funzione async, vedi la sezione Guida alla migrazione Done Callback.
test
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number | TestOptions) => voidAlias:
ittestdefinisce un insieme di aspettative correlate. Riceve il nome del test e una funzione che contiene le asserzioni da testare.Opzionalmente, puoi fornire un timeout (in millisecondi) per specificare il tempo massimo di attesa prima di terminare l'esecuzione del test. Il valore predefinito è di 5 secondi e può essere configurato globalmente con testTimeout.
tsimport { expect, test } from 'vitest'; test('should work as expected', () => { expect(Math.sqrt(4)).toBe(2); });
test.extend
Tipo:
<T extends Record<string, any>>(fixtures: Fixtures<T>): TestAPI<ExtraContext & T>Alias:
it.extendVersione: Vitest 0.32.3
Usa
test.extendper estendere il contesto del test con fixture personalizzate. Questo restituirà un nuovotestche è ulteriormente estendibile, quindi puoi comporre più fixture o sovrascrivere quelle esistenti estendendolo come necessario. Vedi Estendi il contesto del test per maggiori informazioni.tsimport { 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
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number | TestOptions) => voidAlias:
it.skipSe vuoi saltare l'esecuzione di determinati test, ma non vuoi eliminare il codice per qualsiasi motivo, puoi usare
test.skipper impedirne l'esecuzione.tsimport { assert, test } from 'vitest'; test.skip('skipped test', () => { // Test skipped, no error assert.equal(Math.sqrt(4), 3); });Puoi anche saltare il test invocando
skipsul suo contesto dinamicamente:tsimport { assert, test } from 'vitest'; test('skipped test', context => { context.skip(); // Test skipped, no error assert.equal(Math.sqrt(4), 3); });
test.skipIf
Tipo:
(condition: any) => TestAlias:
it.skipIfIn alcuni casi, potresti eseguire i test più volte in ambienti diversi, e alcuni di essi potrebbero essere specifici per un determinato ambiente. Invece di racchiudere il codice del test all'interno di un blocco
if, è possibile utilizzaretest.skipIfper saltare il test qualora la condizione specificata sia valutata cometruthy.tsimport { 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 type checker.
test.runIf
Tipo:
(condition: any) => TestAlias:
it.runIfContrario di test.skipIf.
tsimport { 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 type checker.
test.only
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.onlyUsa
test.onlyper eseguire solo determinati test all'interno di una suite. Questo è utile per il debug.Opzionalmente, puoi fornire un timeout (in millisecondi) per specificare il tempo massimo di attesa prima di terminare l'esecuzione del test. Il valore predefinito è di 5 secondi e può essere configurato globalmente con testTimeout.
tsimport { assert, test } from 'vitest'; test.only('test', () => { // Solo questo test (e altri contrassegnati con only) vengono eseguiti assert.equal(Math.sqrt(4), 2); });A volte è molto utile eseguire test
onlyin un determinato file, ignorando tutti gli altri test dell'intera suite, alterando così l'output.Per fare ciò, esegui
vitestspecificando il file contenente i test in questione.# vitest interesting.test.ts
test.concurrent
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.concurrenttest.concurrentmarca i test consecutivi da eseguire in parallelo. Riceve il nome del test, una funzione asincrona con i test da eseguire e un timeout opzionale (in millisecondi).tsimport { describe, test } from 'vitest'; // I due test contrassegnati con concurrent saranno eseguiti in parallelo describe('suite', () => { test('serial test', async () => { /* ... */ }); test.concurrent('concurrent test 1', async () => { /* ... */ }); test.concurrent('concurrent test 2', async () => { /* ... */ }); });test.skip,test.onlyetest.todofunzionano con i test concurrenti. Tutte le seguenti combinazioni sono valide:tstest.concurrent(/* ... */); test.skip.concurrent(/* ... */); // or test.concurrent.skip(/* ... */) test.only.concurrent(/* ... */); // or test.concurrent.only(/* ... */) test.todo.concurrent(/* ... */); // or test.concurrent.todo(/* ... */)Quando si eseguono test concurrenti, Snapshots e Assertions devono usare
expectdal Contesto del test locale per garantire l'identificazione del test corretto.tstest.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 type checker.
test.todo
Tipo:
(name: string | Function) => voidAlias:
it.todoUsa
test.todoper creare segnaposto di test da implementare in seguito. Verrà visualizzata una voce nel report dei test, indicando quanti test devono ancora essere implementati.ts// Verrà visualizzata una voce nel report per questo test test.todo('unimplemented test');
test.fails
Tipo:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.failsUsa
test.failsper indicare che un'asserzione fallirà intenzionalmente.tsimport { 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 type checker.
test.each
Tipo:
(cases: ReadonlyArray<T>, ...args: any[]) => voidAlias:
it.eachUsa
test.eachquando devi eseguire lo stesso test con input diversi. È possibile inserire parametri con formattazione printf nel nome del test, nell'ordine dei parametri della funzione di test.%s: stringa%d: numero%i: intero%f: valore a virgola mobile%j: json%o: oggetto%#: indice del caso di test%%: singolo segno di percentuale ('%')
tstest.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) -> 3Puoi anche accedere alle proprietà dell'oggetto con il prefisso
$, se stai usando oggetti come argomenti:tstest.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) -> 3Puoi anche accedere agli attributi dell'oggetto con
., se stai usando oggetti come argomenti:tstest.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) -> 3bA partire da Vitest 0.25.3, puoi anche usare la tabella delle stringhe modello.
- La prima riga dovrebbe contenere i nomi delle colonne, separati da
|; - Una o più righe successive di dati forniti come espressioni letterali modello usando la sintassi
${value}.
tstest.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); });Se vuoi avere accesso a
TestContext, usadescribe.eachcon un singolo test.
TIP
Vitest elabora $values con il metodo format di chai. Se il valore viene troncato eccessivamente, puoi aumentare chaiConfig.truncateThreshold nel tuo file di configurazione.
WARNING
Non puoi usare questa sintassi quando usi Vitest come type checker.
bench
- Tipo:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
bench definisce un benchmark. In 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 internamente la libreria tinybench, ereditandone tutte le opzioni, che possono essere utilizzate come terzo argomento.
import { bench } from 'vitest';
bench(
'normal sorting',
() => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
},
{ time: 1000 }
);export interface Options {
/**
* Tempo necessario per l'esecuzione di un'attività di benchmark (in millisecondi)
* @default 500
*/
time?: number;
/**
* Numero di ripetizioni dell'attività, anche se l'opzione time è scaduta
* @default 10
*/
iterations?: number;
/**
* Funzione per ottenere il timestamp corrente in millisecondi
*/
now?: () => number;
/**
* Un segnale AbortSignal per interrompere il benchmark
*/
signal?: AbortSignal;
/**
* Tempo di riscaldamento (in millisecondi)
* @default 100ms
*/
warmupTime?: number;
/**
* Cicli 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;
}bench.skip
- Tipo:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Puoi usare la sintassi bench.skip per saltare l'esecuzione di determinati benchmark.
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
Usa bench.only per eseguire solo determinati benchmark all'interno di una suite. Questo è utile per il debug.
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
Usa bench.todo per creare segnaposto di benchmark da implementare in seguito.
import { bench } from 'vitest';
bench.todo('unimplemented test');describe
Quando si usa test o bench a livello superiore di un file, questi vengono raccolti come parte della suite implicita per quel file. Utilizzando describe puoi definire una nuova suite nel contesto corrente, intesa come un insieme di test o benchmark correlati, eventualmente annidata con altre suite. Una suite ti permette di organizzare i tuoi test e benchmark in modo che i report siano più chiari e leggibili.
// 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);
});
});// 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;
});
});
});Puoi anche annidare blocchi describe se hai una gerarchia di test o benchmark:
import { describe, expect, test } from 'vitest';
function numberToCurrency(value) {
if (typeof value !== 'number') throw new Error('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
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidUsa
describe.skipin una suite per evitare di eseguire un particolare bloccodescribe.tsimport { assert, describe, test } from 'vitest'; describe.skip('skipped suite', () => { test('sqrt', () => { // Suite skipped, no error assert.equal(Math.sqrt(4), 3); }); });
describe.skipIf
Tipo:
(condition: any) => voidIn alcuni casi, potresti voler eseguire le suite in ambienti diversi, e alcune di esse potrebbero essere specifiche per un determinato ambiente. Invece di racchiudere la suite all'interno di un blocco
if, puoi usaredescribe.skipIfper saltare la suite quando la condizione specificata è truthy (vera).tsimport { describe, test } from 'vitest'; const isDev = process.env.NODE_ENV === 'development'; describe.skipIf(isDev)('prod only test', () => { // this test only runs in production });
WARNING
Non puoi usare questa sintassi quando usi Vitest come type checker.
describe.only
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidUsa
describe.onlyper eseguire solo determinate suite.ts// Only this suite (and others marked with only) are run describe.only('suite', () => { test('sqrt', () => { assert.equal(Math.sqrt(4), 3); }); }); describe('other suite', () => { // ... will be skipped });A volte è utile eseguire solo i test contrassegnati con
onlyin un determinato file, escludendo tutti gli altri test della suite, per avere un output più chiaro.Per fare ciò, esegui
vitestcon il file specificato contenente i test in questione.# vitest interesting.test.ts
describe.concurrent
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voiddescribe.concurrentin una suite contrassegna ogni test come concorrente.ts// All tests within this suite will be run in parallel describe.concurrent('suite', () => { test('concurrent test 1', async () => { /* ... */ }); test('concurrent test 2', async () => { /* ... */ }); test.concurrent('concurrent test 3', async () => { /* ... */ }); });.skip,.onlye.todofunzionano con le suite concorrenti. Tutte le seguenti combinazioni sono valide:tsdescribe.concurrent(/* ... */); describe.skip.concurrent(/* ... */); // or describe.concurrent.skip(/* ... */) describe.only.concurrent(/* ... */); // or describe.concurrent.only(/* ... */) describe.todo.concurrent(/* ... */); // or describe.concurrent.todo(/* ... */)
Quando si eseguono test concorrenti, le asserzioni e gli snapshot devono utilizzare expect dal Contesto di Test locale, per assicurarsi che venga individuato il test corretto.
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 type checker.
describe.sequential
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voiddescribe.sequentialin una suite contrassegna ogni test come sequenziale. Questo è utile se si desidera eseguire test in sequenza all'interno di un bloccodescribe.concurrento utilizzando l'opzione da riga di comando--sequence.concurrent.tsdescribe.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
Tipo:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidVitest offre la possibilità di eseguire tutti i test in ordine casuale tramite il flag CLI
--sequence.shuffleo l'opzione di configurazionesequence.shuffle; tuttavia, se si desidera eseguire solo una parte della suite di test in ordine casuale, è possibile contrassegnare quella sezione specifica.tsdescribe.shuffle('suite', () => { test('random test 1', async () => { /* ... */ }); test('random test 2', async () => { /* ... */ }); test('random test 3', async () => { /* ... */ }); }); // order depends on sequence.seed option in config (Date.now() by default)
.skip, .only e .todo funzionano con le suite casuali.
WARNING
Non puoi usare questa sintassi quando usi Vitest come type checker.
describe.todo
Tipo:
(name: string | Function) => voidUsa
describe.todoper creare bozze di suite da implementare in seguito. Verrà mostrata una voce nel report per i test, in modo da sapere quanti test devi ancora implementare.ts// An entry will be shown in the report for this suite describe.todo('unimplemented suite');
describe.each
Tipo:
(cases: ReadonlyArray<T>, ...args: any[]): (name: string | Function, fn: (...args: T[]) => void, options?: number | TestOptions) => voidUsa
describe.eachse hai più di un test che dipende dagli stessi dati.tsdescribe.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 modello.
- La prima riga dovrebbe contenere i nomi delle colonne, separati da
|; - Una o più righe successive di dati forniti come espressioni di template literal usando la sintassi
${value}.
tsdescribe.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); }); });- La prima riga dovrebbe contenere i nomi delle colonne, separati da
WARNING
Non puoi usare questa sintassi quando usi Vitest come type checker.
Setup and Teardown
Queste funzioni ti permettono di agganciarti al "lifecycle" dei test per evitare di ripetere il codice di configurazione e pulizia. Si applicano al contesto corrente: al file, se utilizzate a livello più alto, o alla suite corrente, se inserite all'interno di un blocco describe. Questi hook non vengono eseguiti quando si usa Vitest come type checker.
beforeEach
Tipo:
beforeEach(fn: () => Awaitable<void>, timeout?: number)Registra una callback che verrà eseguita prima di ciascun test nel contesto corrente. Se la funzione restituisce una Promise, Vitest attenderà che la Promise si risolva prima di eseguire il test.
Opzionalmente, puoi passare un "timeout" (in millisecondi) che definisce per quanto tempo aspettare prima di terminare. Il valore predefinito è 5 secondi.
tsimport { beforeEach } from 'vitest'; beforeEach(async () => { // Clear mocks and add some testing data before each test run await stopMocking(); await addUser({ name: 'John' }); });Qui,
beforeEachassicura che l'utente venga aggiunto prima di ogni test.A partire da Vitest v0.10.0,
beforeEachaccetta anche una funzione di cleanup opzionale (funzionalità equivalente aafterEach).tsimport { beforeEach } from 'vitest'; beforeEach(async () => { // called once before each test run await prepareSomething(); // clean up function, called once after each test run return async () => { await resetSomething(); }; });
afterEach
Tipo:
afterEach(fn: () => Awaitable<void>, timeout?: number)Registra una callback che verrà eseguita al termine di ciascun test nel contesto corrente. Se la funzione restituisce una Promise, Vitest attenderà che la Promise si risolva prima di continuare.
Opzionalmente, puoi fornire un "timeout" (in millisecondi) per specificare per quanto tempo aspettare prima di terminare. Il valore predefinito è 5 secondi.
tsimport { afterEach } from 'vitest'; afterEach(async () => { await clearTestingData(); // clear testing data after each test run });Qui,
afterEachassicura che i dati per i test vengano cancellati dopo l'esecuzione di ciascun test.
beforeAll
Tipo:
beforeAll(fn: () => Awaitable<void>, timeout?: number)Registra una callback che verrà eseguita una sola volta, prima dell'inizio di tutti i test nel contesto corrente. Se la funzione restituisce una Promise, Vitest attenderà che la Promise si risolva prima di eseguire i test.
Opzionalmente, puoi fornire un "timeout" (in millisecondi) per specificare per quanto tempo aspettare prima di terminare. Il valore predefinito è 5 secondi.
tsimport { beforeAll } from 'vitest'; beforeAll(async () => { await startMocking(); // called once before all tests run });Qui
beforeAllassicura che i dati di mock siano impostati prima dell'esecuzione dei test.A partire da Vitest v0.10.0,
beforeAllaccetta anche una funzione di cleanup opzionale (funzionalità equivalente aafterAll).tsimport { beforeAll } from 'vitest'; beforeAll(async () => { // called once before all tests run await startMocking(); // clean up function, called once after all tests run return async () => { await stopMocking(); }; });
afterAll
Tipo:
afterAll(fn: () => Awaitable<void>, timeout?: number)Registra una callback che verrà eseguita una sola volta, al termine di tutti i test nel contesto corrente. Se la funzione restituisce una Promise, Vitest attenderà che la Promise si risolva prima di continuare.
Opzionalmente, puoi fornire un "timeout" (in millisecondi) per specificare per quanto tempo aspettare prima di terminare. Il valore predefinito è 5 secondi.
tsimport { afterAll } from 'vitest'; afterAll(async () => { await stopMocking(); // this method is called after all tests run });Qui
afterAllassicura che il metodostopMockingvenga chiamato dopo che tutti i test sono stati eseguiti.