Kontext testu
Inspirováno Playwright Fixtures, kontext testu ve Vitest vám umožňuje definovat nástroje, utility, stavy a fixtures, které můžete využít ve svých testech.
Použití
Každá testovací funkce (callback) obdrží jako první argument kontext testu.
import { it } from 'vitest';
it('should work', ctx => {
// vypíše název testu
console.log(ctx.task.name);
});Vestavěný kontext testu
context.task
Obsahuje metadata aktuálního testu a je určen pouze pro čtení.
context.expect
API expect vázané na aktuální test:
import { it } from 'vitest';
it('math is easy', ({ expect }) => {
expect(2 + 2).toBe(4);
});Toto API je užitečné pro souběžné provádění snapshot testů, protože globální expect s nimi nemůže správně pracovat:
import { it } from 'vitest';
it.concurrent('math is easy', ({ expect }) => {
expect(2 + 2).toMatchInlineSnapshot();
});
it.concurrent('math is hard', ({ expect }) => {
expect(2 * 2).toMatchInlineSnapshot();
});context.skip
Přeskočí provádění testu a označí test jako přeskočený:
import { expect, it } from 'vitest';
it('math is hard', ({ skip }) => {
skip();
expect(2 + 2).toBe(5);
});Rozšíření kontextu testu
Vitest nabízí dva způsoby, jak rozšířit kontext testu.
test.extend
WARNING
Toto API je k dispozici od verze Vitest 0.32.3.
Stejně jako Playwright, můžete použít tuto metodu k definování vlastního API test s vlastními přípravky (fixtures) a používat ho opakovaně.
Například nejprve vytvoříme myTest se dvěma přípravky, todos a archive.
// my-test.ts
import { test } from 'vitest';
const todos = [];
const archive = [];
export const myTest = test.extend({
todos: async ({ task }, use) => {
// nastavení přípravku před každou testovací funkcí
todos.push(1, 2, 3);
// použití hodnoty přípravku
await use(todos);
// vyčištění přípravku po každé testovací funkci
todos.length = 0;
},
archive,
});Poté jej můžeme importovat a použít.
import { expect } from 'vitest';
import { myTest } from './my-test.ts';
myTest('add items to todos', ({ todos }) => {
expect(todos.length).toBe(3);
todos.push(4);
expect(todos.length).toBe(4);
});
myTest('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);
});Můžeme také přidat další přípravky nebo přepsat stávající přípravky rozšířením myTest.
export const myTest2 = myTest.extend({
settings: {
// ...
},
});Inicializace Fixtures
Vitest automaticky inicializuje fixtures a vloží je do kontextu testu podle toho, jak je používáte.
import { test } from 'vitest';
async function todosFn({ task }, use) {
await use([1, 2, 3]);
}
const myTest = test.extend({
todos: todosFn,
archive: [],
});
// todosFn se nespustí
myTest('', () => {});
myTest('', ({ archive }) => {});
// todosFn se spustí
myTest('', ({ todos }) => {});WARNING
Při použití test.extend() s přípravky doporučujeme používat destrukturalizaci objektu { todos } pro přístup ke kontextu jak ve fixture, tak v testovací funkci.
Automatická fixture
WARNING
Tato funkce je k dispozici od verze Vitest 1.3.0.
Vitest také podporuje syntaxi n-tic pro fixtures, což vám umožňuje předávat možnosti pro každou fixture. Můžete ji například použít k explicitní inicializaci fixture, i když se v testech nepoužívá.
import { test as base } from 'vitest';
const test = base.extend({
fixture: [
async ({}, use) => {
// tato funkce bude spuštěna
setup();
await use();
teardown();
},
{ auto: true }, // Označit jako automatickou fixture
],
});
test('', () => {});TypeScript
Pokud chcete definovat typy přípravků pro vaše kontexty, můžete použít generika.
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 a afterEach
Každý test má svůj vlastní kontext. Můžete je používat a rozšiřovat v hookách beforeEach a afterEach.
import { beforeEach, it } from 'vitest';
beforeEach(async context => {
// rozšíření kontextu testu
context.foo = 'bar';
});
it('should work', ({ foo }) => {
console.log(foo); // 'bar'
});TypeScript
Pro definování typů vlastností pro vaše kontexty můžete rozšířit typ TestContext pomocí deklarace modulu:
declare module 'vitest' {
export interface TestContext {
foo?: string;
}
}Pokud chcete definovat typy vlastností jen pro určité hooky beforeEach, afterEach, it a test, můžete použít generika.
interface LocalTestContext {
foo: string;
}
beforeEach<LocalTestContext>(async context => {
// typeof context is 'TestContext & LocalTestContext'
context.foo = 'bar';
});
it<LocalTestContext>('should work', ({ foo }) => {
// typeof foo is 'string'
console.log(foo); // 'bar'
});