Caratteristiche
- Configurazione, trasformatori, risolutori e plugin di Vite
- Utilizza la stessa configurazione della tua app per eseguire i test!
- Modalità di osservazione intelligente e immediata, simile a HMR per i test!
- Test dei componenti per Vue, React, Svelte, Lit, Marko e altro
- Supporto TypeScript / JSX pronto all'uso
- ESM prima di tutto,
await
di primo livello - Multi-threading dei worker tramite Tinypool
- Supporto per il benchmarking con Tinybench
- Filtraggio, timeout e concorrenza per suite e test
- Supporto ai Progetti
- Snapshot compatibile con Jest
- Chai integrato per le asserzioni + API compatibili con Jest expect
- Tinyspy integrato per il mocking
- happy-dom o jsdom per il mocking del DOM
- Modalità Browser per eseguire i test dei componenti nel browser
- Copertura del codice tramite v8 o istanbul
- Test in-source in stile Rust
- Test dei tipi tramite expect-type
- Supporto allo Sharding
- Segnalazione errori non gestiti
Configurazione Condivisa tra Test, Sviluppo e Build
Vitest sfrutta la configurazione, i trasformatori, i risolutori e i plugin di Vite, permettendoti di utilizzare la stessa configurazione della tua app per eseguire i test.
Per maggiori informazioni, consulta Configurazione di Vitest.
Modalità Watch
$ vitest
Quando modifichi il codice sorgente o i file di test, Vitest analizza in modo intelligente il grafo dei moduli ed esegue solo i test correlati, proprio come avviene con HMR in Vite!
vitest
si avvia in watch mode
per impostazione predefinita nell'ambiente di sviluppo e in run mode
nell'ambiente CI (quando process.env.CI
è presente). Questo comportamento è gestito in modo intelligente. Puoi usare vitest watch
o vitest run
per specificare esplicitamente la modalità desiderata.
Avvia Vitest con il flag --standalone
per mantenerlo in esecuzione in background. Non eseguirà alcun test finché non ci saranno modifiche. Vitest non eseguirà i test se il codice sorgente viene modificato, a meno che il test che importa la sorgente non sia stato eseguito.
Idiomi Web Comuni Pronti all'Uso
Supporto per ES Module / TypeScript / JSX / PostCSS pronto all'uso.
Thread
Per impostazione predefinita, Vitest esegue i file di test in più processi utilizzando node:child_process
tramite Tinypool (un fork leggero di Piscina), permettendo ai test di essere eseguiti simultaneamente. Se desideri velocizzare ulteriormente la tua suite di test, considera di abilitare --pool=threads
per eseguire i test utilizzando node:worker_threads
(tieni presente che alcuni pacchetti potrebbero non funzionare con questa configurazione).
Per eseguire i test in un singolo thread o processo, vedi poolOptions
.
Vitest isola anche l'ambiente di ogni file, in modo che le modifiche all'ambiente in un file non influenzino gli altri. L'isolamento può essere disabilitato passando --no-isolate
alla CLI (sacrificando la correttezza per migliorare le prestazioni di esecuzione).
Filtro dei Test
Vitest offre molti modi per restringere i test da eseguire, al fine di accelerare i test e permetterti di concentrarti sullo sviluppo.
Maggiori informazioni su Filtro dei Test.
Esecuzione Concorrente dei Test
Utilizza .concurrent
nei test consecutivi per avviarli in parallelo.
import { describe, it } from 'vitest';
// I due test contrassegnati come concurrent verranno avviati in parallelo
describe('suite', () => {
it('serial test', async () => {
/* ... */
});
it.concurrent('concurrent test 1', async ({ expect }) => {
/* ... */
});
it.concurrent('concurrent test 2', async ({ expect }) => {
/* ... */
});
});
Se usi .concurrent
su una suite, ogni test al suo interno verrà eseguito in parallelo.
import { describe, it } from 'vitest';
// Tutti i test all'interno di questa suite verranno eseguiti in parallelo
describe.concurrent('suite', () => {
it('concurrent test 1', async ({ expect }) => {
/* ... */
});
it('concurrent test 2', async ({ expect }) => {
/* ... */
});
it.concurrent('concurrent test 3', async ({ expect }) => {
/* ... */
});
});
Puoi anche usare .skip
, .only
e .todo
con suite e test concorrenti. Per ulteriori dettagli, consulta il Riferimento API.
WARNING
Quando si eseguono test concorrenti, gli Snapshot e le Asserzioni devono utilizzare expect
dal Contesto di Test locale per assicurarsi che il test corretto venga rilevato.
Snapshot
Supporto per snapshot compatibile con Jest.
import { expect, it } from 'vitest';
it('renders correctly', () => {
const result = render();
expect(result).toMatchSnapshot();
});
Maggiori informazioni su Snapshot.
Compatibilità con Chai e Jest expect
Chai è integrato per le asserzioni, con API compatibili con Jest expect
.
Nota che se stai utilizzando librerie di terze parti che aggiungono matcher, impostare test.globals
su true
garantirà una migliore compatibilità.
Mocking
Tinyspy è integrato per il mocking, con API compatibili con jest
sull'oggetto vi
.
import { expect, vi } from 'vitest';
const fn = vi.fn();
fn('hello', 1);
expect(vi.isMockFunction(fn)).toBe(true);
expect(fn.mock.calls[0]).toEqual(['hello', 1]);
fn.mockImplementation((arg: string) => arg);
fn('world', 2);
expect(fn.mock.results[1].value).toBe('world');
Vitest supporta sia happy-dom che jsdom per il mocking del DOM e delle API del browser. Non sono inclusi in Vitest, dovrai installarli separatamente:
$ npm i -D happy-dom
$ npm i -D jsdom
Dopodiché, modifica l'opzione environment
nel tuo file di configurazione:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'happy-dom', // o 'jsdom', 'node'
},
});
Maggiori informazioni su Mocking.
Copertura
Vitest supporta la copertura del codice nativa tramite v8
e la copertura del codice strumentata tramite istanbul
.
{
"scripts": {
"test": "vitest",
"coverage": "vitest run --coverage"
}
}
Maggiori informazioni su Copertura.
Test In-Source
Vitest fornisce anche un modo per eseguire i test all'interno del tuo codice sorgente insieme all'implementazione, simile ai test dei moduli di Rust.
Questo permette ai test di condividere la stessa closure delle implementazioni e di testare stati privati senza esportare. Nel frattempo, avvicina anche il ciclo di feedback per lo sviluppo.
// l'implementazione
export function add(...args: number[]): number {
return args.reduce((a, b) => a + b, 0);
}
// suite di test in-source
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest;
it('add', () => {
expect(add()).toBe(0);
expect(add(1)).toBe(1);
expect(add(1, 2, 3)).toBe(6);
});
}
Maggiori informazioni su Test in-source.
Benchmarking Sperimentale
Puoi eseguire test di benchmark con la funzione bench
, tramite Tinybench, per confrontare i risultati delle prestazioni.
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;
});
});
});
Test dei Tipi Sperimentale
Puoi scrivere test per rilevare regressioni di tipo. Vitest include il pacchetto expect-type
per fornirti un'API simile e di facile comprensione.
import { assertType, expectTypeOf, test } from 'vitest';
import { mount } from './mount.js';
test('i miei tipi sono corretti', () => {
expectTypeOf(mount).toBeFunction();
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();
// @ts-expect-error name è una stringa
assertType(mount({ name: 42 }));
});
Sharding
Esegui i test su macchine diverse utilizzando i flag --shard
e --reporter=blob
. Tutti i risultati dei test e della copertura possono essere uniti alla fine della tua pipeline CI utilizzando il comando --merge-reports
:
vitest --shard=1/2 --reporter=blob --coverage
vitest --shard=2/2 --reporter=blob --coverage
vitest --merge-reports --reporter=junit --coverage
Consulta Migliorare le Prestazioni | Sharding
per ulteriori informazioni.
Variabili d'Ambiente
Vitest carica automaticamente solo le variabili d'ambiente con prefisso VITE_
dai file .env
per mantenere la compatibilità con i test relativi al frontend, in conformità con la convenzione stabilita da Vite. Per caricare comunque tutte le variabili d'ambiente dai file .env
, puoi utilizzare il metodo loadEnv
importato da vite
:
import { loadEnv } from 'vite';
import { defineConfig } from 'vitest/config';
export default defineConfig(({ mode }) => ({
test: {
// mode definisce quale file ".env.{mode}" scegliere, se esiste.
env: loadEnv(mode, process.cwd(), ''),
},
}));
Errori Non Gestiti
Per impostazione predefinita, Vitest cattura e segnala tutte le promesse non gestite, le eccezioni non catturate (in Node.js) e gli eventi di errore (nel browser).
Puoi disabilitare questo comportamento gestendoli manualmente. Vitest presumerà che il callback sia gestito da te e non segnalerà l'errore.
// in Node.js
process.on('unhandledRejection', () => {
// il tuo gestore personalizzato
});
process.on('uncaughtException', () => {
// il tuo gestore personalizzato
});
// nel browser
window.addEventListener('error', () => {
// il tuo gestore personalizzato
});
window.addEventListener('unhandledrejection', () => {
// il tuo gestore personalizzato
});
In alternativa, puoi anche ignorare gli errori segnalati con l'opzione dangerouslyIgnoreUnhandledErrors
. Vitest li segnalerà comunque, ma non influenzeranno il risultato del test (il codice di uscita non verrà modificato).
Se hai bisogno di verificare che un errore non sia stato catturato, puoi creare un test simile a questo:
test('la mia funzione genera un errore non gestito', async ({ onTestFinished }) => {
onTestFinished(() => {
// se l'evento non è mai stato invocato durante il test,
// assicurati che venga rimosso prima dell'inizio del test successivo
process.removeAllListeners('unhandledrejection');
});
return new Promise((resolve, reject) => {
process.once('unhandledrejection', error => {
try {
expect(error.message).toBe('my error');
resolve();
} catch (error) {
reject(error);
}
});
callMyFunctionThatRejectsError();
});
});