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,
awaitdi 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
$ vitestQuando 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 jsdomDopodiché, 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 --coverageConsulta 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();
});
});