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

Contexto de prueba ​

Inspirado en Playwright Fixtures, el contexto de prueba de Vitest te permite definir utilidades, estados y fixtures que pueden ser utilizados en tus pruebas.

Uso ​

El primer argumento de cada callback de prueba es un contexto de prueba.

ts
import { it } from 'vitest';

it('should work', ({ task }) => {
  // imprime el nombre de la prueba
  console.log(task.name);
});

Contexto de prueba incorporado ​

task ​

Un objeto de solo lectura que contiene metadatos sobre la prueba.

expect ​

La API expect vinculada a la prueba actual:

ts
import { it } from 'vitest';

it('math is easy', ({ expect }) => {
  expect(2 + 2).toBe(4);
});

Esta API es útil para ejecutar pruebas de snapshot de manera concurrente, ya que el expect global no puede rastrearlas:

ts
import { it } from 'vitest';

it.concurrent('math is easy', ({ expect }) => {
  expect(2 + 2).toMatchInlineSnapshot();
});

it.concurrent('math is hard', ({ expect }) => {
  expect(2 * 2).toMatchInlineSnapshot();
});

skip ​

ts
function skip(note?: string): never;
function skip(condition: boolean, note?: string): void;

Omite la ejecución subsiguiente de la prueba y la marca como omitida:

ts
import { expect, it } from 'vitest';

it('math is hard', ({ skip }) => {
  skip();
  expect(2 + 2).toBe(5);
});

Desde Vitest 3.1, acepta un parámetro booleano para omitir la prueba condicionalmente:

ts
it('math is hard', ({ skip, mind }) => {
  skip(mind === 'foggy');
  expect(2 + 2).toBe(5);
});

annotate 3.2.0+ ​

ts
function annotate(
  message: string,
  attachment?: TestAttachment
): Promise<TestAnnotation>;

function annotate(
  message: string,
  type?: string,
  attachment?: TestAttachment
): Promise<TestAnnotation>;

Agrega una anotación de prueba que será mostrada por tu reportero.

ts
test('annotations API', async ({ annotate }) => {
  await annotate('https://github.com/vitest-dev/vitest/pull/7953', 'issues');
});

signal 3.2.0+ ​

Un AbortSignal que puede ser abortado por Vitest. La señal se aborta en estas situaciones:

  • La prueba excede el tiempo límite.
  • El usuario canceló manualmente la ejecución de la prueba con Ctrl+C.
  • Se llamó programáticamente a vitest.cancelCurrentRun.
  • Otra prueba falló en paralelo y la bandera bail está configurada.
ts
it('stop request when test times out', async ({ signal }) => {
  await fetch('/resource', { signal });
}, 2000);

onTestFailed ​

El hook onTestFailed vinculado a la prueba actual. Esta API es útil si estás ejecutando pruebas concurrentemente y necesitas un manejo especial solo para esta prueba específica.

onTestFinished ​

El hook onTestFinished vinculado a la prueba actual. Esta API es útil si estás ejecutando pruebas concurrentemente y necesitas un manejo especial solo para esta prueba específica.

Extender el contexto de prueba ​

Vitest proporciona dos formas diferentes para ayudarte a extender el contexto de prueba.

test.extend ​

Al igual que Playwright, puedes usar este método para definir tu propia API test con fixtures personalizados y reutilizarla en cualquier lugar.

Por ejemplo, primero creamos el recolector test con dos fixtures: todos y archive.

ts
import { test as baseTest } from 'vitest';

const todos = [];
const archive = [];

export const test = baseTest.extend({
  todos: async ({}, use) => {
    // configura el fixture antes de cada función de prueba
    todos.push(1, 2, 3);

    // usa el valor del fixture
    await use(todos);

    // limpia el fixture después de cada función de prueba
    todos.length = 0;
  },
  archive,
});

Luego podemos importarlo y usarlo.

ts
import { expect } from 'vitest';
import { test } from './my-test.js';

test('add items to todos', ({ todos }) => {
  expect(todos.length).toBe(3);

  todos.push(4);
  expect(todos.length).toBe(4);
});

test('move items from todos to archive', ({ todos, archive }) => {
  expect(todos.length).toBe(3);
  expect(archive.length).toBe(0);

  archive.push(todos.pop());
  expect(todos.length).toBe(2);
  expect(archive.length).toBe(1);
});

También podemos añadir más fixtures o sobrescribir los existentes extendiendo nuestro test.

ts
import { test as todosTest } from './my-test.js';

export const test = todosTest.extend({
  settings: {
    // ...
  },
});

Inicialización de fixtures ​

El runner de Vitest inicializará inteligentemente tus fixtures y los inyectará en el contexto de prueba basándose en el uso.

ts
import { test as baseTest } from 'vitest';

const test = baseTest.extend<{
  todos: number[];
  archive: number[];
}>({
  todos: async ({ task }, use) => {
    await use([1, 2, 3]);
  },
  archive: [],
});

// todos no se ejecutará
test('skip', () => {});
test('skip', ({ archive }) => {});

// todos se ejecutará
test('run', ({ todos }) => {});

WARNING

Al usar test.extend() con fixtures, siempre debes usar el patrón de desestructuración de objetos { todos } para acceder al contexto tanto en la función del fixture como en la de prueba.

ts
test('context must be destructured', (context) => { 
  expect(context.todos.length).toBe(2)
})

test('context must be destructured', ({ todos }) => { 
  expect(todos.length).toBe(2)
})

Fixture automático ​

Vitest también soporta la sintaxis de tupla para fixtures, permitiéndote pasar opciones para cada fixture. Por ejemplo, puedes usarlo para inicializar explícitamente un fixture, incluso si no está siendo usado en las pruebas.

ts
import { test as base } from 'vitest';

const test = base.extend({
  fixture: [
    async ({}, use) => {
      // esta función se ejecutará
      setup();
      await use();
      teardown();
    },
    { auto: true }, // Marcar como un fixture automático
  ],
});

test('works correctly');

Fixture predeterminado ​

Desde Vitest 3, puedes proporcionar diferentes valores en diferentes proyectos. Para habilitar esta característica, pasa { injected: true } a las opciones. Si la clave no se especifica en la configuración del proyecto, se utilizará el valor predeterminado.

ts
import { test as base } from 'vitest';

const test = base.extend({
  url: [
    // valor predeterminado si "url" no está definido en la configuración
    '/default',
    // marca el fixture como "injected" para permitir la sobrescritura
    { injected: true },
  ],
});

test('works correctly', ({ url }) => {
  // url es "/default" en "project-new"
  // url es "/full" en "project-full"
  // url es "/empty" en "project-empty"
});
ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    projects: [
      {
        test: {
          name: 'project-new',
        },
      },
      {
        test: {
          name: 'project-full',
          provide: {
            url: '/full',
          },
        },
      },
      {
        test: {
          name: 'project-empty',
          provide: {
            url: '/empty',
          },
        },
      },
    ],
  },
});

Ámbito de valores por suite 3.1.0+ ​

Desde Vitest 3.1, puedes sobrescribir los valores de contexto por suite y sus hijos usando la API test.scoped:

ts
import { test as baseTest, describe, expect } from 'vitest';

const test = baseTest.extend({
  dependency: 'default',
  dependant: ({ dependency }, use) => use({ dependency }),
});

describe('use scoped values', () => {
  test.scoped({ dependency: 'new' });

  test('uses scoped value', ({ dependant }) => {
    // `dependant` usa el nuevo valor sobrescrito aplicado
    // a todas las pruebas en esta suite
    expect(dependant).toEqual({ dependency: 'new' });
  });

  describe('keeps using scoped value', () => {
    test('uses scoped value', ({ dependant }) => {
      // la suite anidada heredó el valor
      expect(dependant).toEqual({ dependency: 'new' });
    });
  });
});

test('keep using the default values', ({ dependant }) => {
  // la `dependency` está usando el valor predeterminado
  // fuera de la suite con .scoped
  expect(dependant).toEqual({ dependency: 'default' });
});

Esta API es especialmente útil si tienes un valor de contexto que depende de una variable dinámica, como una conexión a la base de datos:

ts
const test = baseTest.extend<{
  db: Database;
  schema: string;
}>({
  db: async ({ schema }, use) => {
    const db = await createDb({ schema });
    await use(db);
    await cleanup(db);
  },
  schema: '',
});

describe('one type of schema', () => {
  test.scoped({ schema: 'schema-1' });

  // ... pruebas
});

describe('another type of schema', () => {
  test.scoped({ schema: 'schema-2' });

  // ... pruebas
});

Contexto por ámbito 3.2.0+ ​

Puedes definir un contexto que se iniciará una vez por archivo o por worker. Se inicia de la misma manera que un fixture regular con un parámetro de objetos:

ts
import { test as baseTest } from 'vitest';

export const test = baseTest.extend({
  perFile: [({}, { use }) => use([]), { scope: 'file' }],
  perWorker: [({}, { use }) => use([]), { scope: 'worker' }],
});

El valor se inicializa la primera vez que cualquier prueba lo ha accedido, a menos que las opciones del fixture tengan auto: true - en este caso, el valor se inicializa antes de que se haya ejecutado cualquier prueba.

ts
const test = baseTest.extend({
  perFile: [
    ({}, { use }) => use([]),
    {
      scope: 'file',
      // siempre ejecuta este hook antes de cualquier prueba
      auto: true,
    },
  ],
});

El ámbito worker ejecutará el fixture una vez por worker. El número de workers en ejecución depende de varios factores. Por defecto, cada archivo se ejecuta en un worker separado, por lo que los ámbitos file y worker funcionan de la misma manera.

Sin embargo, si deshabilitas el aislamiento, el número de workers está limitado por la configuración maxWorkers o poolOptions.

Ten en cuenta que especificar scope: 'worker' al ejecutar pruebas en vmThreads o vmForks funcionará de la misma manera que scope: 'file'. Esta limitación existe porque cada archivo de prueba tiene su propio contexto de VM, por lo que si Vitest lo iniciara una vez, un contexto podría filtrarse a otro y crear muchas inconsistencias de referencia (instancias de la misma clase harían referencia a diferentes constructores, por ejemplo).

TypeScript ​

Para proporcionar tipos de fixture para todos tus contextos personalizados, puedes pasar el tipo de fixtures como un genérico.

ts
interface MyFixtures {
  todos: number[];
  archive: number[];
}

const test = baseTest.extend<MyFixtures>({
  todos: [],
  archive: [],
});

test('types are defined correctly', ({ todos, archive }) => {
  expectTypeOf(todos).toEqualTypeOf<number[]>();
  expectTypeOf(archive).toEqualTypeOf<number[]>();
});

Inferencia de tipos

Ten en cuenta que Vitest no soporta la inferencia de tipos cuando se llama a la función use. Siempre es preferible pasar el tipo de contexto completo como el tipo genérico cuando se llama a test.extend:

ts
import { test as baseTest } from 'vitest';

const test = baseTest.extend<{
  todos: number[];
  schema: string;
}>({
  todos: ({ schema }, use) => use([]),
  schema: 'test',
});

test('types are correct', ({
  todos, // number[]
  schema, // string
}) => {
  // ...
});

beforeEach y afterEach ​

Obsoleto

Esta es una forma anticuada de extender el contexto y no funcionará cuando test se extienda con test.extend.

Los contextos son diferentes para cada prueba. Puedes acceder a ellos y extenderlos dentro de los hooks beforeEach y afterEach.

ts
import { beforeEach, it } from 'vitest';

beforeEach(async context => {
  // extiende el contexto
  context.foo = 'bar';
});

it('should work', ({ foo }) => {
  console.log(foo); // 'bar'
});

TypeScript ​

Para proporcionar tipos de propiedades para todos tus contextos personalizados, puedes aumentar el tipo TestContext añadiendo

ts
declare module 'vitest' {
  export interface TestContext {
    foo?: string;
  }
}

Si deseas proporcionar tipos de propiedades solo para hooks beforeEach, afterEach, it y test específicos, puedes pasar el tipo como un genérico.

ts
interface LocalTestContext {
  foo: string;
}

beforeEach<LocalTestContext>(async context => {
  // typeof context es 'TestContext & LocalTestContext'
  context.foo = 'bar';
});

it<LocalTestContext>('should work', ({ foo }) => {
  // typeof foo es 'string'
  console.log(foo); // 'bar'
});
Pager
AnteriorPruebas en el código fuente
SiguienteAnotaciones de prueba

Publicado bajo la licencia MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/guide/test-context

Publicado bajo la licencia MIT.

Copyright (c) 2021-Present Vitest Team