Características
- Configuración, transformadores, resolvedores y complementos de Vite
- ¡Utiliza la misma configuración de tu aplicación para ejecutar las pruebas!
- Modo de observación inteligente e instantáneo, ¡como HMR para pruebas!
- Pruebas de componentes para Vue, React, Svelte, Lit, Marko y más
- Soporte nativo para TypeScript / JSX
- Prioridad a ESM,
top level await
- Ejecución multihilo mediante workers a través de Tinypool
- Soporte de benchmarking con Tinybench
- Filtrado, tiempos de espera y concurrencia para suites y pruebas
- Soporte para Proyectos
- Snapshots compatibles con Jest
- Chai integrado para aserciones + APIs compatibles con Jest expect
- Tinyspy integrado para simulación (mocking)
- happy-dom o jsdom para simulación del DOM
- Modo Navegador para ejecutar pruebas de componentes en el navegador
- Cobertura de código mediante v8 o istanbul
- Pruebas en el código fuente al estilo de Rust
- Pruebas de tipos a través de expect-type
- Soporte de Sharding
- Reporte de errores no capturados
Configuración compartida entre pruebas, desarrollo y compilación
Vitest aprovecha la configuración, los transformadores, los resolvedores y los complementos de Vite. Esto te permite usar la misma configuración de tu aplicación para ejecutar las pruebas.
Aprende más en Configurando Vitest.
Modo de observación
$ vitest
Cuando modificas tu código fuente o los archivos de prueba, Vitest busca inteligentemente en el gráfico de módulos y solo re-ejecuta las pruebas relacionadas, ¡justo como funciona HMR en Vite!
vitest
se inicia en watch mode
por defecto en el entorno de desarrollo y en run mode
en el entorno de CI (cuando process.env.CI
está presente) de forma inteligente. Puedes usar vitest watch
o vitest run
para especificar explícitamente el modo deseado.
Inicia Vitest con la bandera --standalone
para mantenerlo ejecutándose en segundo plano. No ejecutará ninguna prueba hasta que cambien. Vitest no volverá a ejecutar pruebas si el código fuente se modifica, a menos que la prueba que importa dicho código fuente ya haya sido ejecutada.
Idiomas web comunes listos para usar
Soporte nativo para módulos ES / TypeScript / JSX / PostCSS.
Hilos
Por defecto, Vitest ejecuta archivos de prueba en múltiples procesos utilizando node:child_process
a través de Tinypool (un fork ligero de Piscina), permitiendo que las pruebas se ejecuten simultáneamente. Si quieres acelerar aún más tu suite de pruebas, considera habilitar --pool=threads
para ejecutar pruebas usando node:worker_threads
(ten en cuenta que algunos paquetes podrían no funcionar con esta configuración).
Para ejecutar pruebas en un solo hilo o proceso, consulta poolOptions
.
Vitest también aísla el entorno de cada archivo para que los cambios en el entorno de un archivo no afecten a otros. El aislamiento se puede deshabilitar pasando --no-isolate
a la CLI (comprometiendo la corrección en aras del rendimiento de ejecución).
Filtrado de pruebas
Vitest ofrece muchas formas de limitar las pruebas a ejecutar para acelerar el proceso y permitirte concentrarte en el desarrollo.
Aprende más sobre el Filtrado de pruebas.
Ejecución de pruebas concurrentemente
Usa .concurrent
en pruebas individuales para iniciarlas en paralelo.
import { describe, it } from 'vitest';
// Las dos pruebas marcadas como concurrentes se iniciarán en paralelo
describe('suite', () => {
it('serial test', async () => {
/* ... */
});
it.concurrent('concurrent test 1', async ({ expect }) => {
/* ... */
});
it.concurrent('concurrent test 2', async ({ expect }) => {
/* ... */
});
});
Si usas .concurrent
en una suite, todas las pruebas dentro de ella se iniciarán en paralelo.
import { describe, it } from 'vitest';
// Todas las pruebas dentro de esta suite se iniciarán en paralelo
describe.concurrent('suite', () => {
it('concurrent test 1', async ({ expect }) => {
/* ... */
});
it('concurrent test 2', async ({ expect }) => {
/* ... */
});
it.concurrent('concurrent test 3', async ({ expect }) => {
/* ... */
});
});
También puedes usar .skip
, .only
y .todo
con suites y pruebas concurrentes. Lee más en la Referencia de la API.
WARNING
Al ejecutar pruebas concurrentes, los Snapshots y las Aserciones deben usar expect
del Contexto de prueba local para garantizar que se asocie a la prueba correcta.
Snapshot
Soporte para snapshots compatibles con Jest.
import { expect, it } from 'vitest';
it('renders correctly', () => {
const result = render();
expect(result).toMatchSnapshot();
});
Aprende más en Snapshot.
Compatibilidad con Chai y Jest expect
Chai está integrado para las aserciones con APIs compatibles con Jest expect
.
Ten en cuenta que si estás utilizando librerías de terceros que añaden matchers, establecer test.globals
en true
proporcionará una mejor compatibilidad.
Mocking
Tinyspy está integrado para el mocking con APIs compatibles con jest
en el objeto 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 soporta tanto happy-dom como jsdom para la simulación del DOM y las APIs del navegador. No se incluyen con Vitest, necesitarás instalarlos por separado:
$ npm i -D happy-dom
$ npm i -D jsdom
Después de eso, modifica la opción environment
en tu archivo de configuración:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'happy-dom', // o 'jsdom', 'node'
},
});
Aprende más en Mocking.
Cobertura
Vitest soporta cobertura de código nativa mediante v8
y cobertura de código instrumentado mediante istanbul
.
{
"scripts": {
"test": "vitest",
"coverage": "vitest run --coverage"
}
}
Aprende más en Cobertura.
Pruebas en el código fuente
Vitest también proporciona un método para ejecutar pruebas dentro de tu código fuente junto con la implementación, similar a las pruebas de módulo de Rust.
Esto permite que las pruebas compartan el mismo cierre que las implementaciones y puedan probar estados privados sin exportar. Al mismo tiempo, también optimiza el ciclo de retroalimentación para el desarrollo.
// la implementación
export function add(...args: number[]): number {
return args.reduce((a, b) => a + b, 0);
}
// suites de prueba en el código fuente
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);
});
}
Aprende más en Pruebas en el código fuente.
Benchmarking Experimental
Puedes ejecutar pruebas de rendimiento con la función bench
mediante Tinybench para comparar resultados de rendimiento.
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;
});
});
});
Pruebas de tipos Experimental
Puedes escribir pruebas para detectar regresiones de tipos. Vitest incluye el paquete expect-type
para proporcionarte una API similar y fácil de entender.
import { assertType, expectTypeOf, test } from 'vitest';
import { mount } from './mount.js';
test('my types work properly', () => {
expectTypeOf(mount).toBeFunction();
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();
// @ts-expect-error name is a string
assertType(mount({ name: 42 }));
});
Sharding
Ejecuta pruebas en diferentes máquinas usando las banderas --shard
y --reporter=blob
. Todos los resultados de las pruebas y la cobertura se pueden fusionar al final de tu pipeline de CI mediante el comando --merge-reports
:
vitest --shard=1/2 --reporter=blob --coverage
vitest --shard=2/2 --reporter=blob --coverage
vitest --merge-reports --reporter=junit --coverage
Consulta Mejora del rendimiento | Sharding
para más información.
Variables de entorno
Vitest carga automáticamente las variables de entorno con el prefijo VITE_
de los archivos .env
para mantener la compatibilidad con las pruebas relacionadas con el frontend, siguiendo la convención establecida de Vite. Para cargar todas las variables de entorno de los archivos .env
en cualquier caso, puedes usar el método loadEnv
importado de vite
:
import { loadEnv } from 'vite';
import { defineConfig } from 'vitest/config';
export default defineConfig(({ mode }) => ({
test: {
// mode define qué archivo ".env.{mode}" seleccionar si existe
env: loadEnv(mode, process.cwd(), ''),
},
}));
Errores no manejados
Por defecto, Vitest captura y reporta todos los rechazos de promesas no manejados, excepciones no capturadas (en Node.js) y eventos de error (en el navegador).
Puedes deshabilitar este comportamiento capturándolos manualmente. Vitest asume que tú manejas el callback y no reportará el error.
// en Node.js
process.on('unhandledRejection', () => {
// tu propio manejador
});
process.on('uncaughtException', () => {
// tu propio manejador
});
// en el navegador
window.addEventListener('error', () => {
// tu propio manejador
});
window.addEventListener('unhandledrejection', () => {
// tu propio manejador
});
Alternativamente, también puedes ignorar los errores reportados con la opción dangerouslyIgnoreUnhandledErrors
. Vitest seguirá reportándolos, pero no afectarán el resultado de la prueba (el código de salida no cambiará).
Si necesitas probar que un error no fue capturado, puedes crear una prueba que tenga la siguiente estructura:
test('my function throws uncaught error', async ({ onTestFinished }) => {
onTestFinished(() => {
// si el evento nunca se invocó durante la prueba,
// asegúrate de que se eliminen los listeners antes de que comience la siguiente prueba
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();
});
});