Spouštěč testů
WARNING
Toto je pokročilé rozhraní API. Pokud chcete pouze spouštět testy, pravděpodobně ho nepotřebujete. Používají ho především autoři knihoven.
Cestu ke svému spouštěči testů můžete specifikovat pomocí volby runner
v konfiguračním souboru. Tento soubor by měl mít defaultní export s konstruktorem třídy, která implementuje následující metody:
export interface VitestRunner {
/**
* První metoda volaná před samotným sběrem a spuštěním testů.
*/
onBeforeCollect?: (paths: string[]) => unknown;
/**
* Voláno po sběru testů a před "onBeforeRun".
*/
onCollected?: (files: File[]) => unknown;
/**
* Voláno, když by spouštěč testů měl zrušit další spuštění testů.
* Spouštěč by měl naslouchat této metodě a při jejím volání označit testy a sady jako přeskočené v
* "onBeforeRunSuite" a "onBeforeRunTask".
*/
onCancel?: (reason: CancelReason) => unknown;
/**
* Voláno před spuštěním jednoho testu. Zatím nemá "result".
*/
onBeforeRunTest?: (test: TaskPopulated) => unknown;
/**
* Voláno před samotným spuštěním testovací funkce. Už má "result" se "state" a "startTime".
*/
onBeforeTryTask?: (
test: TaskPopulated,
options: { retry: number; repeats: number }
) => unknown;
/**
* Voláno po nastavení výsledku a stavu.
*/
onAfterRunTask?: (test: TaskPopulated) => unknown;
/**
* Voláno hned po spuštění testovací funkce. Nový stav ještě není k dispozici. Není voláno, pokud testovací funkce vyhodí chybu.
*/
onAfterTryTask?: (
test: TaskPopulated,
options: { retry: number; repeats: number }
) => unknown;
/**
* Voláno před spuštěním jedné sady. Ještě nemá "result".
*/
onBeforeRunSuite?: (suite: Suite) => unknown;
/**
* Voláno po spuštění jedné sady. Má stav a výsledek.
*/
onAfterRunSuite?: (suite: Suite) => unknown;
/**
* Pokud je definováno, bude voláno místo obvyklého zpracování sady Vitest.
* Hooky "before" a "after" nebudou ignorovány.
*/
runSuite?: (suite: Suite) => Promise<void>;
/**
* Pokud je definováno, bude voláno místo obvyklého zpracování úkolu Vitest. Užitečné, pokud máte vlastní testovací funkci.
* Hooky "before" a "after" nebudou ignorovány.
*/
runTask?: (test: TaskPopulated) => Promise<void>;
/**
* Voláno, když je úkol aktualizován. Je to ekvivalent "onTaskUpdate" v reportéru, ale toto běží ve stejném vlákně jako testy.
*/
onTaskUpdate?: (task: [string, TaskResult | undefined][]) => Promise<void>;
/**
* Voláno před spuštěním všech testů v sebraných cestách.
*/
onBeforeRunFiles?: (files: File[]) => unknown;
/**
* Voláno hned po spuštění všech testů v sebraných cestách.
*/
onAfterRunFiles?: (files: File[]) => unknown;
/**
* Voláno, když je definován nový kontext pro test. To je užitečné, pokud chcete přidat vlastní vlastnosti do kontextu.
* Pokud chcete pouze definovat vlastní kontext se spouštěčem, zvažte použití "beforeAll" v "setupFiles" místo toho.
*
* Tato metoda je volána pro "test" i "custom" handlery.
*
* @see https://www.getbook.com/en/book/vitest-2/advanced/runner#your-task-function
*/
extendTaskContext?: <T extends Test | Custom>(
context: TaskContext<T>
) => TaskContext<T>;
/**
* Voláno, když jsou importovány určité soubory. K tomu může dojít ve dvou situacích: při sběru testů a při importu souborů nastavení.
*/
importFile: (filepath: string, source: VitestRunnerImportSource) => unknown;
/**
* Veřejně dostupná konfigurace.
*/
config: VitestRunnerConfig;
}
Při inicializaci této třídy Vitest předává konfiguraci Vitest, kterou byste měli vystavit jako vlastnost config
.
WARNING
Vitest také vkládá instanci ViteNodeRunner
jako vlastnost __vitest_executor
. Můžete ji použít ke zpracování souborů v metodě importFile
(což je výchozí chování TestRunner
a BenchmarkRunner
).
ViteNodeRunner
vystavuje metodu executeId
, která se používá k importu testovacích souborů v prostředí přátelském k Vite. V době běhu tak vyřeší importy a transformuje obsah souboru tak, aby mu Node rozuměl.
TIP
Podpora snapshotů a některé další funkce závisí na spouštěči. Pokud o ně nechcete přijít, můžete svůj spouštěč rozšířit z VitestTestRunner
importovaného z vitest/runners
. Pro rozšíření funkcionality benchmarků vystavuje také BenchmarkNodeRunner
.
Úkoly
Sady a testy se interně nazývají tasks
. Spouštěč Vitest inicializuje úkol File
před sběrem jakýchkoli testů - jedná se o nadmnožinu Suite
s několika dalšími vlastnostmi. Je k dispozici u každého úkolu (včetně File
) jako vlastnost file
.
interface File extends Suite {
/**
* Název fondu, do kterého soubor patří.
* @default 'forks'
*/
pool?: string;
/**
* Cesta k souboru ve formátu UNIX.
*/
filepath: string;
/**
* Název projektu pracovního prostoru, do kterého soubor patří.
*/
projectName: string | undefined;
/**
* Čas v milisekundách, který trvalo sebrat všechny testy v souboru.
* Tento čas zahrnuje také import všech závislostí souboru.
*/
collectDuration?: number;
/**
* Čas v milisekundách, který trvalo importovat soubor nastavení.
*/
setupDuration?: number;
/**
* Zda je soubor inicializován bez spuštění jakýchkoli testů.
* To se provádí za účelem naplnění stavu na straně serveru pomocí Vitest.
*/
local?: boolean;
}
Každá sada má vlastnost tasks
, která se naplní během fáze sběru. To je užitečné pro procházení stromu úkolů shora dolů.
interface Suite extends TaskBase {
type: 'suite';
/**
* Úkol souboru. Je to kořenový úkol souboru.
*/
file: File;
/**
* Pole úkolů, které jsou součástí sady.
*/
tasks: Task[];
}
Každý úkol má vlastnost suite
, která odkazuje na sadu, ve které je umístěn. Pokud jsou test
nebo describe
inicializovány na nejvyšší úrovni, nebudou mít vlastnost suite
(a nebude rovna file
!). File
také nikdy nemá vlastnost suite
. To je užitečné pro procházení úkolů zdola nahoru.
interface Test<ExtraContext = object> extends TaskBase {
type: 'test';
/**
* Kontext testu, který se předá testovací funkci.
*/
context: TaskContext<Test> & ExtraContext & TestContext;
/**
* Úkol souboru. Je to kořenový úkol souboru.
*/
file: File;
/**
* Zda byl úkol přeskočen voláním `t.skip()`.
*/
pending?: boolean;
/**
* Zda se má úkol považovat za úspěšný, i když selže. Pokud úkol selže, bude označen jako úspěšný.
*/
fails?: boolean;
/**
* Háčky, které se spustí, pokud úkol selže. Jejich pořadí závisí na možnosti `sequence.hooks`.
*/
onFailed?: OnTestFailedHandler[];
/**
* Háčky, které se spustí po dokončení úkolu. Jejich pořadí závisí na možnosti `sequence.hooks`.
*/
onFinished?: OnTestFinishedHandler[];
/**
* Ukládá sliby (z asynchronních očekávání), na které se čeká před dokončením testu.
*/
promises?: Promise<any>[];
}
Každý úkol může mít vlastnost result
. Sady mohou mít tuto vlastnost pouze v případě, že chyba vyhozená v rámci zpětného volání sady nebo zpětných volání beforeAll
/afterAll
zabrání sběru testů. Testy mají tuto vlastnost vždy po volání jejich zpětných volání - vlastnosti state
a errors
jsou přítomny v závislosti na výsledku. Pokud byla chyba vyhozena ve zpětných voláních beforeEach
nebo afterEach
, vyhozená chyba bude obsažena v task.result.errors
.
export interface TaskResult {
/**
* Stav úkolu. Během sběru dědí `task.mode`.
* Po dokončení úkolu se změní na `pass` nebo `fail`.
* - **pass**: úkol proběhl úspěšně
* - **fail**: úkol selhal
*/
state: TaskState;
/**
* Chyby, které nastaly během provádění úkolu. Může se vyskytnout několik chyb,
* pokud `expect.soft()` selhalo vícekrát.
*/
errors?: ErrorWithDiff[];
/**
* Doba v milisekundách, po kterou úkol běžel.
*/
duration?: number;
/**
* Čas v milisekundách, kdy úkol začal běžet.
*/
startTime?: number;
/**
* Velikost haldy v bajtech po dokončení úkolu.
* K dispozici pouze, pokud je nastavena možnost `logHeapUsage` a je definováno `process.memoryUsage`.
*/
heap?: number;
/**
* Stav háčků souvisejících s tímto úkolu. To je užitečné při reportování.
*/
hooks?: Partial<
Record<'afterAll' | 'beforeAll' | 'beforeEach' | 'afterEach', TaskState>
>;
/**
* Počet opakování úkolu. Úkol se opakuje pouze, pokud selhal
* a je nastavena možnost `retry`.
*/
retryCount?: number;
/**
* Počet opakování úkolu. Úkol se opakuje pouze, pokud
* je nastavena možnost `repeats`. Toto číslo zahrnuje také `retryCount`.
*/
repeatCount?: number;
}
Vaše funkce úkolu
Vitest poskytuje typ úkolu Custom
, který umožňuje uživatelům znovu použít vestavěné reportéry. Je prakticky stejný jako Test
, ale má typ 'custom'
.
Úkol je objekt, který je součástí sady. Je automaticky přidán do aktuální sady pomocí metody suite.task
:
// ./utils/custom.js
import { createTaskCollector, getCurrentSuite, setFn } from 'vitest/suite';
export { afterAll, beforeAll, describe } from 'vitest';
// tato funkce bude volána během fáze sběru:
// nevolat zde funkci handleru, přidat ji k úkolům sady
// metodou "getCurrentSuite().task()"
// Poznámka: createTaskCollector poskytuje podporu pro "todo"/"each"/...
export const myCustomTask = createTaskCollector(function (name, fn, timeout) {
getCurrentSuite().task(name, {
...this, // takže "todo"/"skip"/... je správně sledováno
meta: {
customPropertyToDifferentiateTask: true,
},
handler: fn,
timeout,
});
});
// ./garden/tasks.test.js
import { afterAll, beforeAll, describe, myCustomTask } from '../custom.js';
import { gardener } from './gardener.js';
describe('take care of the garden', () => {
beforeAll(() => {
gardener.putWorkingClothes();
});
myCustomTask('weed the grass', () => {
gardener.weedTheGrass();
});
myCustomTask.todo('mow the lawn', () => {
gardener.mowerTheLawn();
});
myCustomTask('water flowers', () => {
gardener.waterFlowers();
});
afterAll(() => {
gardener.goHome();
});
});
vitest ./garden/tasks.test.js
WARNING
Pokud nemáte vlastní spouštěč nebo jste nedefinovali metodu runTest
, Vitest se pokusí úkol automaticky načíst. Pokud jste nepřidali funkci pomocí setFn
, selže.