Contexto de prueba
Inspirado por Playwright Fixtures, el contexto de prueba de Vitest te permite definir herramientas, estados y fixtures que pueden ser usados en tus pruebas.
Uso
El primer argumento para cada callback de prueba es un contexto de prueba.
import { it } from 'vitest';
it('debería funcionar', ctx => {
// imprime el nombre de la prueba
console.log(ctx.task.name);
});
Contexto de Prueba Integrado
context.task
Un objeto de solo lectura que contiene metadatos de la prueba.
context.expect
La API expect
enlazada a la prueba actual:
import { it } from 'vitest';
it('las matemáticas son fáciles', ({ expect }) => {
expect(2 + 2).toBe(4);
});
Esta API es útil para ejecutar pruebas instantáneas concurrentemente porque el expect
global no puede rastrearlas:
import { it } from 'vitest';
it.concurrent('las matemáticas son fáciles', ({ expect }) => {
expect(2 + 2).toMatchInlineSnapshot();
});
it.concurrent('las matemáticas son difíciles', ({ expect }) => {
expect(2 * 2).toMatchInlineSnapshot();
});
context.skip
Omite la ejecución posterior de la prueba y la marca como omitida:
import { expect, it } from 'vitest';
it('las matemáticas son difíciles', ({ skip }) => {
skip();
expect(2 + 2).toBe(5);
});
Extender el Contexto de Prueba
Vitest ofrece dos formas de extender el contexto de prueba.
test.extend
WARNING
Esta API está disponible desde Vitest 0.32.3.
Al igual que Playwright, puedes usar este método para definir tu propia API test
con fixtures personalizadas y reutilizarla en cualquier lugar.
Por ejemplo, primero creamos myTest
con dos fixtures, todos
y archive
.
// my-test.ts
import { test } from 'vitest';
const todos = [];
const archive = [];
export const myTest = test.extend({
todos: async ({ task }, 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.
import { expect } from 'vitest';
import { myTest } from './my-test.ts';
myTest('agrega elementos a todos', ({ todos }) => {
expect(todos.length).toBe(3);
todos.add(4);
expect(todos.length).toBe(4);
});
myTest('mueve elementos de todos a 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 agregar más fixtures o sobrescribir fixtures existentes extendiendo myTest
.
export const myTest2 = myTest.extend({
settings: {
// ...
},
});
Inicialización de Fixtures
El ejecutor de Vitest inicializará tus fixtures de manera inteligente y los inyectará en el contexto de prueba según su uso.
import { test } from 'vitest';
async function todosFn({ task }, use) {
await use([1, 2, 3]);
}
const myTest = test.extend({
todos: todosFn,
archive: [],
});
// todosFn no se ejecutará
myTest('', () => {});
myTest('', ({ archive }) => {});
// todosFn se ejecutará
myTest('', ({ todos }) => {});
WARNING
Al usar test.extend()
con fixtures, siempre debes usar la desestructuración de objetos { todos }
para acceder al contexto, tanto en la función fixture como en la función de prueba.
TypeScript
Para proporcionar tipos de fixture para todos tus contextos personalizados, puedes pasar el tipo de fixtures como un genérico.
interface MyFixtures {
todos: number[];
archive: number[];
}
const myTest = test.extend<MyFixtures>({
todos: [],
archive: [],
});
myTest('', context => {
expectTypeOf(context.todos).toEqualTypeOf<number[]>();
expectTypeOf(context.archive).toEqualTypeOf<number[]>();
});
beforeEach
y afterEach
Los contextos son distintos para cada prueba. Puedes acceder a ellos y extenderlos dentro de los hooks beforeEach
y afterEach
.
import { beforeEach, it } from 'vitest';
beforeEach(async context => {
// extiende el contexto
context.foo = 'bar';
});
it('debería funcionar', ({ foo }) => {
console.log(foo); // 'bar'
});
TypeScript
Para proporcionar tipos de propiedad para todos tus contextos personalizados, puedes agregar el tipo TestContext
mediante
declare module 'vitest' {
export interface TestContext {
foo?: string;
}
}
Si deseas proporcionar tipos de propiedad solo para hooks beforeEach
, afterEach
, it
y test
específicos, puedes pasar el tipo como un genérico.
interface LocalTestContext {
foo: string;
}
beforeEach<LocalTestContext>(async context => {
// typeof context is 'TestContext & LocalTestContext'
context.foo = 'bar';
});
it<LocalTestContext>('debería funcionar', ({ foo }) => {
// typeof foo is 'string'
console.log(foo); // 'bar'
});