Skip to content
Vitest 3
Main Navigation Guía & APIConfiguraciónModo NavegadorAPI avanzada
3.2.0
2.1.9
1.6.1
0.34.6

Español

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

Español

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

Apariencia

Sidebar Navigation

Introducción

Por qué Vitest

Primeros pasos

Características

Configuración de Vitest

API

Referencia de la API de prueba

Funciones de Simulación

Vi

expect

expectTypeOf

assert

assertType

Guía

Interfaz de línea de comandos

Filtrado de Tests

Proyectos de prueba

Reportes

Cobertura

Instantáneas

Simulación (Mocking)

Paralelismo

Pruebas de Tipado

Interfaz de usuario de Vitest

Pruebas en el código fuente

Contexto de prueba

Anotaciones de prueba

Entorno de pruebas

Extender Matchers

Integraciones con IDE

Depuración

Errores comunes

Guía de migración

Migración a Vitest 3.0

Migración desde Jest

Rendimiento

Perfilado del rendimiento de las pruebas

Mejorando el Rendimiento

Modo Navegador

API Avanzadas

Comparaciones con otros ejecutores de pruebas

En esta página

Guía de migración ​

Migración a Vitest 3.0 ​

Opciones de Prueba como Tercer Argumento ​

Vitest 3.0 emitirá una advertencia si se pasa un objeto como tercer argumento a las funciones test o describe:

ts
test('validation works', () => {
  // ...
}, { retry: 3 }); 

test('validation works', { retry: 3 }, () => { 
  // ...
});

La próxima versión principal lanzará un error si el tercer argumento es un objeto. Sin embargo, el valor del tiempo de espera sigue siendo válido:

ts
test('validation works', () => {
  // ...
}, 1000); // Ok ✅

browser.name y browser.providerOptions están Obsoletos ​

Tanto browser.name como browser.providerOptions serán eliminados en Vitest 4. En su lugar, utiliza la nueva opción browser.instances:

ts
export default defineConfig({
  test: {
    browser: {
      name: 'chromium', 
      providerOptions: { 
        launch: { devtools: true }, 
      }, 
      instances: [ 
        { 
          browser: 'chromium', 
          launch: { devtools: true }, 
        }, 
      ], 
    },
  },
})

Con el nuevo campo browser.instances, también puedes especificar múltiples configuraciones de navegador.

spy.mockReset Ahora Restaura la Implementación Original ​

Anteriormente, no existía una forma adecuada de restablecer un espía a su implementación original sin tener que reconfigurarlo. Ahora, spy.mockReset restablecerá la implementación del mock a la original en lugar de a una función no-op simulada.

ts
const foo = {
  bar: () => 'Hello, world!',
};

vi.spyOn(foo, 'bar').mockImplementation(() => 'Hello, mock!');

foo.bar(); // 'Hello, mock!'

foo.bar.mockReset();

foo.bar(); // undefined
foo.bar(); // 'Hello, world!'

vi.spyOn Reutiliza el Mock si el Método ya está Simulado ​

Anteriormente, Vitest siempre asignaba un nuevo espía al espiar un objeto. Esto causaba errores con mockRestore, ya que restauraba el espía anterior en lugar de la función original:

ts
vi.spyOn(fooService, 'foo').mockImplementation(() => 'bar');
vi.spyOn(fooService, 'foo').mockImplementation(() => 'bar');
vi.restoreAllMocks();
vi.isMockFunction(fooService.foo); // true
vi.isMockFunction(fooService.foo); // false

Valores Predeterminados de Temporizadores Simulados ​

Vitest ya no incluye opciones predeterminadas para fakeTimers.toFake. Ahora, Vitest simulará cualquier API relacionada con temporizadores si está disponible (excepto nextTick). En particular, performance.now() ahora se simula cuando se llama a vi.useFakeTimers.

ts
vi.useFakeTimers();

performance.now(); // original
performance.now(); // fake

Puedes revertir al comportamiento anterior especificando explícitamente los temporizadores al llamar a vi.useFakeTimers o configurándolos globalmente:

ts
export default defineConfig({
  test: {
    fakeTimers: {
      toFake: [ 
        'setTimeout', 
        'clearTimeout', 
        'setInterval', 
        'clearInterval', 
        'setImmediate', 
        'clearImmediate', 
        'Date', 
      ] 
    },
  },
})

Igualdad de Errores Más Estricta ​

Vitest ahora verifica más propiedades al comparar errores usando toEqual o toThrowError. Vitest compara name, message, cause y AggregateError.errors. Para Error.cause, la comparación es asimétrica:

ts
expect(new Error('hi', { cause: 'x' })).toEqual(new Error('hi')); // ✅
expect(new Error('hi')).toEqual(new Error('hi', { cause: 'x' })); // ❌

Además de verificar más propiedades, Vitest ahora compara los prototipos de los errores. Por ejemplo, si se lanzó un TypeError, la verificación de igualdad debe ser de tipo TypeError, no Error:

ts
expect(() => {
  throw new TypeError('type error');
})
  .toThrowError(new Error('type error')) 
  .toThrowError(new TypeError('type error')); 

Para más detalles, consulta el PR: #5876.

La Exportación Condicional module no se Resuelve por Defecto en Vite 6 ​

Vite 6 permite opciones resolve.conditions más flexibles, y Vitest las configura para excluir la exportación condicional module por defecto. Consulta también la guía de migración de Vite 6 para obtener detalles sobre los cambios del lado de Vite.

El Tipo Custom está Obsoleto API ​

El tipo Custom ahora es un alias para el tipo Test. Ten en cuenta que Vitest actualizó los tipos públicos en 2.1 y cambió los nombres exportados a RunnerCustomCase y RunnerTestCase:

ts
import {
  RunnerCustomCase, 
  RunnerTestCase, 
} from 'vitest';

Si estás usando getCurrentSuite().custom(), el type de la tarea devuelta ahora será 'test'. El tipo Custom se eliminará en Vitest 4.

El Tipo WorkspaceSpec Ya No se Utiliza API ​

En la API pública, este tipo se utilizaba anteriormente en secuenciadores personalizados. Por favor, migra a TestSpecification en su lugar.

onTestFinished y onTestFailed Ahora Reciben un Contexto ​

Los hooks onTestFinished y onTestFailed anteriormente recibían el resultado de la prueba como primer argumento. Ahora, al igual que beforeEach y afterEach, reciben un contexto de prueba.

Cambios en la API de Snapshots API ​

La API pública de Snapshots en @vitest/snapshot se modificó para admitir múltiples estados en una única ejecución. Consulta el PR para más detalles: #6817

Cabe destacar que estos cambios solo afectan a los desarrolladores que usan la API de Snapshots directamente. No hubo cambios en la API de .toMatchSnapshot.

Cambios en la Firma del Tipo resolveConfig API ​

resolveConfig ahora ofrece mayor utilidad. En lugar de aceptar una configuración de Vite ya resuelta, ahora acepta una configuración de usuario y devuelve la configuración resuelta.

Esta función no se utiliza internamente y se expone únicamente como una API pública.

Tipos de vitest/reporters Simplificados API ​

El punto de entrada vitest/reporters ahora exporta únicamente las implementaciones de los reporteros y sus tipos de opciones. Si necesitas acceso a TestCase/TestSuite y otros tipos relacionados con tareas, impórtalos también desde vitest/node.

La Cobertura Ignora los Archivos de Prueba Incluso Cuando coverage.excludes se Anula ​

Ya no es posible incluir archivos de prueba en el informe de cobertura anulando coverage.excludes. Los archivos de prueba ahora siempre se excluyen.

Migración a Vitest 2.0 ​

El Pool Predeterminado es forks ​

Vitest 2.0 establece la configuración predeterminada de pool a 'forks' para una mejor estabilidad. Puedes leer la motivación completa en el PR.

Si has utilizado poolOptions sin haber especificado un pool, es posible que necesites actualizar la configuración:

ts
export default defineConfig({
  test: {
    poolOptions: {
      threads: { 
        singleThread: true, 
      }, 
      forks: { 
        singleFork: true, 
      }, 
    }
  }
})

Los Hooks se Ejecutan en Secuencia ​

Antes de Vitest 2.0, todos los hooks se ejecutaban en paralelo. A partir de la versión 2.0, se ejecutan secuencialmente. Además, los hooks afterAll/afterEach se ejecutan en orden inverso.

Para revertir a la ejecución paralela de los hooks, cambia sequence.hooks a 'parallel':

ts
export default defineConfig({
  test: {
    sequence: { 
      hooks: 'parallel', 
    }, 
  },
})

suite.concurrent Ejecuta Todas las Pruebas Concurrentemente ​

Anteriormente, especificar concurrent en una suite agrupaba las pruebas concurrentes dentro de cada suite, ejecutándolas secuencialmente. Ahora, siguiendo el comportamiento de Jest, todas las pruebas se ejecutan concurrentemente (respetando los límites de maxConcurrency).

coverage.ignoreEmptyLines para Cobertura V8 está Habilitado por Defecto ​

El valor predeterminado de coverage.ignoreEmptyLines ahora es true. Este cambio significativo puede afectar los informes de cobertura de código y podría requerir ajustes en los umbrales de cobertura para algunos proyectos. Este ajuste solo se aplica a la configuración predeterminada cuando coverage.provider es 'v8'.

Eliminación de la Opción watchExclude ​

Vitest usa el observador de Vite. Excluye archivos o directorios agregándolos a server.watch.ignored:

ts
export default defineConfig({
  server: { 
    watch: { 
      ignored: ['!node_modules/examplejs'] 
    } 
  } 
})

--segfault-retry Eliminado ​

Con los cambios en el pool por defecto, esta opción ya no es necesaria. Si experimentas errores de segfault, prueba a cambiar al pool 'forks'. Si el problema persiste, abre un nuevo issue con una reproducción.

Eliminación de Tareas Vacías en Suites ​

Este es un cambio en la API de tareas avanzada. Anteriormente, recorrer .suite eventualmente conducía a la suite interna vacía que sustituía a una tarea de archivo.

Esto hace que .suite sea opcional: si la tarea se define en el nivel superior, no tendrá una suite asociada. Puedes usar la propiedad .file, que ahora está presente en todas las tareas (incluida la propia tarea de archivo, así que ten cuidado de no caer en una recursión infinita).

Este cambio también elimina la referencia al archivo en expect.getState().currentTestName y hace que expect.getState().testPath sea obligatorio.

task.meta se Incluye en el Reportero JSON ​

El reportero JSON ahora muestra task.meta para cada resultado de aserción.

Tipos Genéricos Simplificados de Funciones Simuladas (ej. vi.fn<T>, Mock<T>) ​

Anteriormente, vi.fn<TArgs, TReturn> aceptaba dos tipos genéricos de forma separada para los argumentos y el valor de retorno. Esto se cambió para aceptar directamente un tipo de función vi.fn<T> para simplificar el uso.

ts
import { vi } from 'vitest';
import type { Mock } from 'vitest';

const add = (x: number, y: number): number => x + y;

// using vi.fn<T>
const mockAdd = vi.fn<Parameters<typeof add>, ReturnType<typeof add>>(); 
const mockAdd = vi.fn<typeof add>(); 

// using Mock<T>
const mockAdd: Mock<Parameters<typeof add>, ReturnType<typeof add>> = vi.fn(); 
const mockAdd: Mock<typeof add> = vi.fn(); 

Acceso a mock.results con Promesas Resueltas ​

Anteriormente, Vitest resolvía los valores de mock.results si la función devolvía una Promesa. Ahora existe una propiedad mock.settledResults separada que se completa únicamente cuando la Promesa devuelta se resuelve o se rechaza.

ts
const fn = vi.fn().mockResolvedValueOnce('result');
await fn();

const result = fn.mock.results[0]; // 'result'
const result = fn.mock.results[0]; // 'Promise<result>'

const settledResult = fn.mock.settledResults[0]; // 'result'

Con este cambio, también introducimos nuevos matchers toHaveResolved*, similares a toHaveReturned, para facilitar la migración si previamente utilizabas este último:

ts
const fn = vi.fn().mockResolvedValueOnce('result');
await fn();

expect(fn).toHaveReturned('result'); 
expect(fn).toHaveResolved('result'); 

Modo Navegador ​

El Modo Navegador de Vitest experimentó muchos cambios durante el ciclo beta. Puedes leer sobre nuestra filosofía en el Modo Navegador en la página de discusión de GitHub.

La mayoría de los cambios fueron aditivos, pero hubo algunos pequeños cambios disruptivos:

  • El proveedor none fue renombrado a preview #5842
  • El proveedor preview ahora es el predeterminado #5842
  • indexScripts fue renombrado a orchestratorScripts #5842

Opciones Obsoletas Retiradas API ​

Se eliminaron algunas opciones obsoletas:

  • Comando vitest typecheck - usa vitest --typecheck en su lugar
  • Variables de entorno VITEST_JUNIT_CLASSNAME y VITEST_JUNIT_SUITE_NAME (usa las opciones del reportero en su lugar)
  • La verificación de cobertura con c8 (usa coverage-v8 en su lugar)
  • Exportación de SnapshotEnvironment desde vitest - impórtalo desde vitest/snapshot en su lugar
  • SpyInstance se elimina a favor de MockInstance

Migración a Vitest 1.0 ​

Requisitos Mínimos ​

Vitest 1.0 requiere Vite 5.0 y Node.js 18 o versiones posteriores.

Todos los subpaquetes @vitest/* requieren Vitest versión 1.0.

Actualización de Snapshots #3961 ​

Las comillas en los snapshots ya no se escapan, y todos los snapshots usan comillas graves (`) incluso para cadenas de una sola línea.

  1. Las comillas ya no se escapan:
diff
expect({ foo: 'bar' }).toMatchInlineSnapshot(`
  Object {
-    \\"foo\\": \\"bar\\",
+    "foo": "bar",
  }
`)
  1. Los snapshots de una línea ahora usan comillas "`" en lugar de ':
diff
- expect('some string').toMatchInlineSnapshot('"some string"')
+ expect('some string').toMatchInlineSnapshot(`"some string"`)

También hubo cambios en el paquete @vitest/snapshot. Si no lo estás usando directamente, no necesitas cambiar nada.

  • Ya no necesitas extender SnapshotClient solo para sobrescribir el método equalityCheck: simplemente pásalo como isEqual al iniciar una instancia
  • client.setTest fue renombrado a client.startCurrentRun
  • client.resetCurrent fue renombrado a client.finishCurrentRun

Los Pools están Estandarizados #4172 ​

Hemos eliminado muchas opciones de configuración para facilitar la adaptación del ejecutor a tus necesidades. Por favor, echa un vistazo a los ejemplos de migración si dependes de --threads u otras banderas relacionadas.

  • --threads ahora es --pool=threads
  • --no-threads ahora es --pool=forks
  • --single-thread ahora es --poolOptions.threads.singleThread
  • --experimental-vm-threads ahora es --pool=vmThreads
  • --experimental-vm-worker-memory-limit ahora es --poolOptions.vmThreads.memoryLimit
  • --isolate ahora es --poolOptions.<pool-name>.isolate y browser.isolate
  • test.maxThreads ahora es test.poolOptions.<pool-name>.maxThreads
  • test.minThreads ahora es test.poolOptions.<pool-name>.minThreads
  • test.useAtomics ahora es test.poolOptions.<pool-name>.useAtomics
  • test.poolMatchGlobs.child_process ahora es test.poolMatchGlobs.forks
  • test.poolMatchGlobs.experimentalVmThreads ahora es test.poolMatchGlobs.vmThreads
diff
{
  scripts: {
-    "test": "vitest --no-threads"
     // For identical behaviour:
+    "test": "vitest --pool forks --poolOptions.forks.singleFork"
     // Or multi parallel forks:
+    "test": "vitest --pool forks"

  }
}
diff
{
  scripts: {
-    "test": "vitest --experimental-vm-threads"
+    "test": "vitest --pool vmThreads"
  }
}
diff
{
  scripts: {
-    "test": "vitest --isolate false"
+    "test": "vitest --poolOptions.threads.isolate false"
  }
}
diff
{
  scripts: {
-    "test": "vitest --no-threads --isolate false"
+    "test": "vitest --pool forks --poolOptions.forks.isolate false"
  }
}

Cambios en la Cobertura #4265, #4442 ​

La opción coverage.all ahora está habilitada de forma predeterminada. Esto significa que todos los archivos del proyecto que coincidan con el patrón coverage.include se procesarán aunque no se ejecuten.

La estructura de la API de umbrales de cobertura ha cambiado, y ahora permite especificar umbrales para archivos específicos utilizando patrones glob:

diff
export default defineConfig({
  test: {
    coverage: {
-      perFile: true,
-      thresholdAutoUpdate: true,
-      100: true,
-      lines: 100,
-      functions: 100,
-      branches: 100,
-      statements: 100,
+      thresholds: {
+        perFile: true,
+        autoUpdate: true,
+        100: true,
+        lines: 100,
+        functions: 100,
+        branches: 100,
+        statements: 100,
+      }
    }
  }
})

Tipos de Mock #4400 ​

Se eliminaron algunos tipos a favor de la nomenclatura "Mock" al estilo Jest.

diff
- import { EnhancedSpy, SpyInstance } from 'vitest'
+ import { MockInstance } from 'vitest'

WARNING

SpyInstance está obsoleto a favor de MockInstance y se eliminará en la próxima versión principal.

Mocks de Temporizadores #3925 ​

vi.useFakeTimers() ya no simula de forma automática process.nextTick. Todavía es posible simular process.nextTick especificándolo explícitamente al usar vi.useFakeTimers({ toFake: ['nextTick'] }).

Sin embargo, la simulación de process.nextTick no es posible al usar --pool=forks. Usa una opción --pool diferente si necesitas simular process.nextTick.

Migración desde Jest ​

Vitest ha sido diseñado con una API compatible con Jest, para hacer la migración desde Jest lo más simple posible. A pesar de esos esfuerzos, aún puedes observar las siguientes diferencias:

Globales por Defecto ​

Jest tiene su API global habilitada por defecto, mientras que Vitest no. Puedes habilitar las globales mediante la configuración globals o actualizar tu código para usar importaciones del módulo vitest.

Si decides mantener las globales deshabilitadas, es importante considerar que las bibliotecas comunes como testing-library no realizarán la limpieza automática del DOM.

spy.mockReset ​

mockReset de Jest reemplaza la implementación del mock con una función vacía que devuelve undefined.

mockReset de Vitest restablece la implementación del mock a su original. Es decir, restablecer un mock creado por vi.fn(impl) restablecerá la implementación del mock a impl.

Mocks de Módulos ​

Al simular un módulo en Jest, el argumento de fábrica devuelve la exportación predeterminada. En Vitest, el argumento de fábrica debe devolver un objeto con cada exportación explícitamente definida. Por ejemplo, el siguiente jest.mock tendría que actualizarse de la siguiente manera:

ts
jest.mock('./some-path', () => 'hello') 
vi.mock('./some-path', () => ({ 
  default: 'hello', 
})) 

Para más detalles, consulta la sección de la API vi.mock.

Comportamiento de Auto-Simulación ​

A diferencia de Jest, los módulos simulados en <root>/__mocks__ no se cargan si no se llama a vi.mock(). Si necesitas que se simulen en cada prueba, como en Jest, puedes configurarlos dentro de setupFiles.

Importar el Original de un Paquete Simulado ​

Si solo estás creando mocks parciales para un paquete, es posible que hayas usado anteriormente la función requireActual de Jest. En Vitest, debes sustituir estas llamadas por vi.importActual.

ts
const { cloneDeep } = jest.requireActual('lodash/cloneDeep'); 
const { cloneDeep } = await vi.importActual('lodash/cloneDeep'); 

Extender la Simulación a Librerías Externas ​

A diferencia de Jest, que extiende la simulación por defecto, cuando simulas un módulo y deseas que esta simulación se aplique también a otras librerías externas que utilizan el mismo módulo, debes especificar explícitamente qué librería de terceros quieres simular. Esto se logra haciendo que la librería externa se considere parte de tu código fuente, utilizando server.deps.inline.

server.deps.inline: ["lib-name"]

expect.getState().currentTestName ​

Los nombres de test de Vitest usan el símbolo > como separador para facilitar la distinción entre pruebas y suites, mientras que Jest usa un espacio vacío ().

diff
- `${describeTitle} ${testTitle}`
+ `${describeTitle} > ${testTitle}`

Variables de Entorno ​

Al igual que Jest, Vitest establece NODE_ENV a test, si no se había establecido antes. Vitest también tiene un equivalente para JEST_WORKER_ID llamado VITEST_POOL_ID (siempre menor o igual a maxThreads), por lo que si dependes de ella, no olvides renombrarla. Vitest también expone VITEST_WORKER_ID, que es un ID único de un worker en ejecución. Este número no se ve afectado por maxThreads y aumentará con cada worker creado.

Sustituir Propiedad ​

En Jest, para modificar un objeto, se utiliza la API replaceProperty. En Vitest, puedes lograr el mismo efecto usando vi.stubEnv o vi.spyOn.

Callback Done ​

A partir de Vitest v0.10.0, el uso de callbacks para declarar pruebas está obsoleto. Puedes reescribirlas para usar funciones async/await, o usar Promesas para simular el comportamiento de los callbacks.

js
it('should work', (done) => {  
it('should work', () => new Promise(done => { 
  // ...
  done()
}) 
})) 

Hooks ​

Los hooks beforeAll/beforeEach pueden devolver una función de desmontaje en Vitest. Debido a esto, es posible que necesites reescribir tus declaraciones de hooks si devuelven algo distinto de undefined o null:

ts
beforeEach(() => setActivePinia(createTestingPinia())) 
beforeEach(() => { setActivePinia(createTestingPinia()) }) 

En Jest, los hooks se llaman secuencialmente. Por defecto, Vitest ejecuta los hooks en paralelo. Para usar el comportamiento de Jest, actualiza la opción sequence.hooks:

ts
export default defineConfig({
  test: {
    sequence: { 
      hooks: 'list', 
    } 
  }
})

Tipos ​

Vitest no tiene un equivalente al espacio de nombres jest, por lo que necesitarás importar los tipos directamente desde vitest:

ts
let fn: jest.Mock<(name: string) => number>; 
import type { Mock } from 'vitest'; 
let fn: Mock<(name: string) => number>; 

Temporizadores ​

Vitest no soporta los temporizadores heredados de Jest.

Tiempo de Espera ​

Si usaste jest.setTimeout, necesitarías migrar a vi.setConfig:

ts
jest.setTimeout(5_000); 
vi.setConfig({ testTimeout: 5_000 }); 

Snapshots de Vue ​

Aunque no es una característica específica de Jest, si anteriormente utilizabas Jest con el preajuste de vue-cli, necesitarás instalar el paquete jest-serializer-vue y configurarlo dentro de setupFiles:

js
import { defineConfig } from 'vite';

export default defineConfig({
  test: {
    setupFiles: ['./tests/unit/setup.js'],
  },
});
js
import vueSnapshotSerializer from 'jest-serializer-vue';

expect.addSnapshotSerializer(vueSnapshotSerializer);

De lo contrario, tus snapshots tendrán muchas comillas escapadas.

Pager
AnteriorErrores comunes
SiguientePerfilado del rendimiento de las pruebas

Publicado bajo la licencia MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/guide/migration

Publicado bajo la licencia MIT.

Copyright (c) 2021-Present Vitest Team