Skip to content
Vitest 3
Main Navigation Průvodce & APIKonfiguraceRežim prohlížečePokročilé API
3.2.0
2.1.9
1.6.1
0.34.6

čeština

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

čeština

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

Vzhled

Sidebar Navigation

Úvod

Proč Vitest

Začínáme

Funkce

Konfigurace Vitestu

API

Testovací reference API

Mockovací funkce

Vi

expect

expectTypeOf

assert

assertType

Průvodce

Rozhraní příkazového řádku

Filtrování testů

Testovací projekty

Generátory zpráv

Pokrytí kódu

Snímky

Mockování

Paralelní zpracování

Typové testování

Vitest UI

Testování přímo ve zdrojovém kódu

Testovací kontext

Anotace testů

Testovací prostředí

Rozšíření matcherů

Integrace s IDE

Ladění

Běžné chyby

Průvodce migrací

Migrace na Vitest 3.0

Migrace z Jest

Výkon

Profilování výkonu testů

Zlepšení výkonu

Režim prohlížeče

Rozšířené API

Srovnání

Na této stránce

Testovací kontext ​

Testovací kontext Vitest, inspirovaný Playwright Fixtures, umožňuje definovat utility, stavy a testovací fixture, které lze použít ve vašich testech.

Použití ​

Prvním argumentem každé callback funkce testu je kontext testu.

ts
import { it } from 'vitest';

it('should work', ({ task }) => {
  // vypíše jméno testu
  console.log(task.name);
});

Vestavěný testovací kontext ​

task ​

Objekt jen pro čtení obsahující metadata o testu.

expect ​

API expect, které je vázáno na aktuální test:

ts
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 je nedokáže sledovat:

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;

Přeskočí následné provádění testu a označí test jako přeskočený:

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

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

Od verze Vitest 3.1 přijímá booleovský parametr pro podmíněné přeskočení testu:

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>;

Přidá anotaci k testu, která bude zobrazena vaším reportérem.

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

signal 3.2.0+ ​

AbortSignal, který může být zrušen Vitestem. Signál je zrušen v následujících situacích:

  • Test vyprší
  • Uživatel ručně zrušil spuštění testu pomocí Ctrl+C
  • vitest.cancelCurrentRun bylo voláno programově
  • Jiný test selhal souběžně a je nastaven příznak bail
ts
it('stop request when test times out', async ({ signal }) => {
  await fetch('/resource', { signal });
}, 2000);

onTestFailed ​

Hook onTestFailed vázaný na aktuální test. Toto API je užitečné, pokud provádíte testy souběžně a potřebujete speciální zpracování pouze pro tento konkrétní test.

onTestFinished ​

Hook onTestFinished vázaný na aktuální test. Toto API je užitečné, pokud provádíte testy souběžně a potřebujete speciální zpracování pouze pro tento konkrétní test.

Rozšíření testovacího kontextu ​

Vitest poskytuje dva různé způsoby, jak vám pomoci rozšířit testovací kontext.

test.extend ​

Podobně jako Playwright, můžete tuto metodu použít k definování vlastního test API s vlastními fixtures a jeho opětovnému použití kdekoli.

Například nejprve vytvoříme instanci test se dvěma fixtures: todos a archive.

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

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

export const test = baseTest.extend({
  todos: async ({}, use) => {
    // nastavit fixture před každou testovací funkcí
    todos.push(1, 2, 3);

    // použít hodnotu fixture
    await use(todos);

    // vyčistit fixture po každé testovací funkci
    todos.length = 0;
  },
  archive,
});

Pak jej můžeme importovat a použít.

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);
});

Můžeme také přidat další fixtures nebo přepsat stávající fixtures rozšířením našeho test.

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

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

Inicializace fixture ​

Vitest runner chytře inicializuje vaše fixtures a vloží je do kontextu testu na základě jejich použití.

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 se nespustí
test('skip', () => {});
test('skip', ({ archive }) => {});

// todos se spustí
test('run', ({ todos }) => {});

WARNING

Při použití test.extend() s fixtures byste měli vždy používat vzorec pro destrukturalizaci objektu { todos } pro přístup ke kontextu jak ve funkci fixture, tak ve funkci testu.

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

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

Automatická fixture ​

Vitest také podporuje syntaxi n-tice pro fixtures, což vám umožňuje předávat možnosti pro každou fixture. Například ji můžete použít k explicitní inicializaci fixture, i když se v testech nepoužívá.

ts
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('works correctly');

Výchozí fixture ​

Od Vitest 3 můžete poskytovat různé hodnoty v různých projektech. Pro povolení této funkce předejte { injected: true } do možností. Pokud klíč není specifikován v konfiguraci projektu, pak bude použita výchozí hodnota.

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

const test = base.extend({
  url: [
    // výchozí hodnota, pokud "url" není definováno v konfiguraci
    '/default',
    // označit fixture jako "injected" pro povolení přepsání
    { injected: true },
  ],
});

test('works correctly', ({ url }) => {
  // url je "/default" v "project-new"
  // url je "/full" v "project-full"
  // url je "/empty" v "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',
          },
        },
      },
    ],
  },
});

Rozsah hodnot pro testovací sadu 3.1.0+ ​

Od Vitest 3.1 můžete přepsat hodnoty kontextu pro každou sadu a její potomky pomocí 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` používá novou přepsanou hodnotu, která je v rozsahu
    // všech testů v této sadě
    expect(dependant).toEqual({ dependency: 'new' });
  });

  describe('keeps using scoped value', () => {
    test('uses scoped value', ({ dependant }) => {
      // vnořená testovací sada zdědila hodnotu
      expect(dependant).toEqual({ dependency: 'new' });
    });
  });
});

test('keep using the default values', ({ dependant }) => {
  // `dependency` používá výchozí
  // hodnotu mimo sadu s .scoped
  expect(dependant).toEqual({ dependency: 'default' });
});

Toto API je obzvláště užitečné, pokud máte hodnotu kontextu, která závisí na dynamické proměnné, jako je připojení k databázi:

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' });

  // ... testy
});

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

  // ... testy
});

Kontext podle rozsahu 3.2.0+ ​

Můžete definovat kontext, který bude inicializován jednou pro soubor nebo worker. Inicializuje se stejným způsobem jako běžná fixture s parametrem objektů:

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

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

Hodnota je inicializována poprvé, když k ní přistoupí jakýkoli test, pokud možnosti fixture nemají auto: true – v tomto případě je hodnota inicializována před spuštěním jakéhokoli testu.

ts
const test = baseTest.extend({
  perFile: [
    ({}, { use }) => use([]),
    {
      scope: 'file',
      // vždy spustit tento hook před jakýmkoli testem
      auto: true,
    },
  ],
});

Rozsah worker spustí fixture jednou pro každého workera. Počet spuštěných workerů závisí na různých faktorech. Ve výchozím nastavení se každý soubor spouští v samostatném workeru, takže rozsahy file a worker fungují stejně.

Pokud však zakážete izolaci, pak je počet workerů omezen konfigurací maxWorkers nebo poolOptions.

Všimněte si, že specifikace scope: 'worker' při spouštění testů v vmThreads nebo vmForks bude fungovat stejně jako scope: 'file'. Toto omezení existuje, protože každý testovací soubor má svůj vlastní VM kontext, takže pokud by ho Vitest inicializoval jednou, jeden kontext by mohl uniknout do druhého a vytvořit mnoho nekonzistencí referencí (například instance stejné třídy by odkazovaly na různé konstruktory).

TypeScript ​

Pro poskytnutí typů fixtures pro všechny vaše vlastní kontexty můžete předat typ fixture jako generický.

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[]>();
});

Odvozování typů

Všimněte si, že Vitest nepodporuje odvozování typů, když je volána funkce use. Vždy je lepší předat celý typ kontextu jako generický typ, když je volán 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 a afterEach ​

Zastaralé

Toto je zastaralý způsob rozšíření kontextu a nebude fungovat, pokud je test rozšířen pomocí test.extend.

Kontexty jsou pro každý test odlišné. Můžete k nim přistupovat a rozšiřovat je v rámci hooků beforeEach a afterEach.

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

beforeEach(async context => {
  // rozšířit kontext
  context.foo = 'bar';
});

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

TypeScript ​

Pro poskytnutí typů vlastností pro všechny vaše vlastní kontexty můžete rozšířit typ TestContext přidáním

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

Pokud chcete poskytnout typy vlastností pouze pro konkrétní hooky beforeEach, afterEach, it a test, můžete předat typ jako generický.

ts
interface LocalTestContext {
  foo: string;
}

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

it<LocalTestContext>('should work', ({ foo }) => {
  // typeof foo je 'string'
  console.log(foo); // 'bar'
});
Pager
Předchozí stránkaTestování přímo ve zdrojovém kódu
Další stránkaAnotace testů

Vydáno pod licencí MIT.

Copyright (c) 2021-Present Vitest Team

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

Vydáno pod licencí MIT.

Copyright (c) 2021-Present Vitest Team