Futtató API
WARNING
Ez egy haladó API. Ha csak teszteket szeretne futtatni, valószínűleg nincs szüksége rá. Elsősorban könyvtárfejlesztők használják.
A runner
opcióval adhatja meg a tesztfuttató elérési útját a konfigurációs fájlban. Ennek a fájlnak egy alapértelmezett exporttal kell rendelkeznie, amely egy osztálykonstruktort tartalmaz, és implementálja ezeket a metódusokat:
export interface VitestRunner {
/**
* Az első metódus, ami meghívódik, mielőtt ténylegesen összegyűjtené és futtatná a teszteket.
*/
onBeforeCollect?: (paths: string[]) => unknown;
/**
* A tesztek összegyűjtése után, de az "onBeforeRun" előtt hívódik meg.
*/
onCollected?: (files: File[]) => unknown;
/**
* Akkor hívódik meg, amikor a tesztfuttatónak meg kell szakítania a következő tesztfuttatásokat.
* A futtatónak figyelnie kell erre a metódusra, és amikor meghívásra kerül, az "onBeforeRunSuite" és "onBeforeRunTask" metódusokban kihagyottként kell megjelölnie a teszteket és csomagokat.
*/
onCancel?: (reason: CancelReason) => unknown;
/**
* Egyetlen teszt futtatása előtt hívódik meg. Az eredmény még nem áll rendelkezésre.
*/
onBeforeRunTask?: (test: TaskPopulated) => unknown;
/**
* A tesztfüggvény tényleges futtatása előtt hívódik meg. Már tartalmazza az "eredményt" a "state" és "startTime" mezőkkel.
*/
onBeforeTryTask?: (
test: TaskPopulated,
options: { retry: number; repeats: number }
) => unknown;
/**
* Az eredmény és az állapot beállítása után fut le.
*/
onAfterRunTask?: (test: TaskPopulated) => unknown;
/**
* Közvetlenül a tesztfüggvény futtatása után fut le. Még nincs új állapota. Nem hívódik meg, ha a tesztfüggvény kivételt dob.
*/
onAfterTryTask?: (
test: TaskPopulated,
options: { retry: number; repeats: number }
) => unknown;
/**
* Egyetlen csomag futtatása előtt hívódik meg. Az eredmény még nem áll rendelkezésre.
*/
onBeforeRunSuite?: (suite: Suite) => unknown;
/**
* Egyetlen csomag futtatása után hívódik meg. Állapottal és eredménnyel is rendelkezik.
*/
onAfterRunSuite?: (suite: Suite) => unknown;
/**
* Ha definiálva van, a szokásos Vitest csomagfelosztás és kezelés helyett fut le.
* A "before" és "after" hookok továbbra is érvényesek lesznek.
*/
runSuite?: (suite: Suite) => Promise<void>;
/**
* Ha definiálva van, a szokásos Vitest kezelés helyett fut le. Hasznos, ha egyedi tesztfüggvénye van.
* A "before" és "after" hookok továbbra is érvényesek lesznek.
*/
runTask?: (test: TaskPopulated) => Promise<void>;
/**
* Akkor hívódik meg, amikor egy feladat frissül. Funkciója megegyezik a riporter "onTaskUpdate" metódusával, de ez ugyanabban a szálban fut, mint a tesztek.
*/
onTaskUpdate?: (
task: [string, TaskResult | undefined, TaskMeta | undefined][]
) => Promise<void>;
/**
* Az összes teszt futtatása előtt fut le az összegyűjtött útvonalakon.
*/
onBeforeRunFiles?: (files: File[]) => unknown;
/**
* Közvetlenül az összes teszt futtatása után fut le az összegyűjtött útvonalakon.
*/
onAfterRunFiles?: (files: File[]) => unknown;
/**
* Akkor fut le, amikor egy teszthez új kontextus van definiálva. Hasznos, ha egyedi tulajdonságokat szeretne hozzáadni a kontextushoz.
* Ha csak egyedi kontextust szeretne definiálni egy futtató segítségével, fontolja meg a "beforeAll" használatát a "setupFiles" fájlokban.
*/
extendTaskContext?: (context: TestContext) => TestContext;
/**
* Akkor fut le, amikor bizonyos fájlokat importálnak. Két esetben hívható meg: tesztek gyűjtésére és beállítási fájlok importálására.
*/
importFile: (filepath: string, source: VitestRunnerImportSource) => unknown;
/**
* Függvény, amely akkor hívódik meg, amikor a futtató megpróbálja lekérni az értéket, amennyiben a `test.extend` `{ injected: true }` beállítással van használva.
*/
injectValue?: (key: string) => unknown;
/**
* Nyilvánosan elérhető konfiguráció.
*/
config: VitestRunnerConfig;
/**
* Az aktuális pool neve. Befolyásolhatja, hogyan következtethető ki a veremkövetés a szerver oldalon.
*/
pool?: string;
}
Az osztály inicializálásakor a Vitest átadja a Vitest konfigurációt – ezt config
tulajdonságként kell elérhetővé tennie:
import type { RunnerTestFile } from 'vitest';
import type { VitestRunner, VitestRunnerConfig } from 'vitest/suite';
import { VitestTestRunner } from 'vitest/runners';
class CustomRunner extends VitestTestRunner implements VitestRunner {
public config: VitestRunnerConfig;
constructor(config: VitestRunnerConfig) {
this.config = config;
}
onAfterRunFiles(files: RunnerTestFile[]) {
console.log('finished running', files);
}
}
export default CustomRunner;
WARNING
A Vitest egy ViteNodeRunner
példányt is átad __vitest_executor
tulajdonságként. Ezt használhatja a fájlok feldolgozására az importFile
metódusban (ez a TestRunner
és BenchmarkRunner
alapértelmezett viselkedése).
A ViteNodeRunner
az executeId
metódust biztosítja, amelyet a tesztfájlok Vite-barát környezetben történő importálására használnak. Ez azt jelenti, hogy futásidőben feloldja az importokat és átalakítja a fájl tartalmát, hogy a Node értelmezni tudja:
export default class Runner {
async importFile(filepath: string) {
await this.__vitest_executor.executeId(filepath);
}
}
WARNING
Ha nincs egyedi futtatója, vagy nem definiálta a runTask
metódust, a Vitest megpróbálja automatikusan betölteni a feladatot. Ha nem adott hozzá függvényt a setFn
segítségével, akkor a művelet sikertelen lesz.
TIP
A pillanatkép-támogatás és néhány más funkció a futtatótól függ. Ha nem szeretné elveszíteni, kiterjesztheti a futtatóját a vitest/runners
fájlból importált VitestTestRunner
osztályból. Ez a BenchmarkNodeRunner
osztályt is biztosítja, ha a benchmark funkciókat szeretné kiterjeszteni.
Feladatok
WARNING
A "Futtató Feladatok API" kísérleti fázisban van, és elsősorban csak a teszt futásidejében használható. A Vitest a "Jelentett Feladatok API-t" is biztosítja, amelyet előnyben kell részesíteni a fő szálban (például a riporteren belül) történő munkavégzéskor.
A csapat jelenleg arról tárgyal, hogy a "Futtató Feladatokat" a jövőben a "Jelentett Feladatok" váltják-e fel.
A csomagokat és teszteket belsőleg tasks
-nak hívjuk. A Vitest futtató egy File
feladatot inicializál, mielőtt bármilyen tesztet gyűjtene – ez egy Suite
típus, kiegészítve néhány további tulajdonsággal. Minden feladaton (beleértve a File
-t is) file
tulajdonságként érhető el.
interface File extends Suite {
/**
* A pool neve, amelyhez a fájl tartozik.
* @default 'forks'
*/
pool?: string;
/**
* A fájl elérési útja UNIX formátumban.
*/
filepath: string;
/**
* A tesztprojekt neve, amelyhez a fájl tartozik.
*/
projectName: string | undefined;
/**
* A fájlban lévő összes teszt összegyűjtéséhez szükséges idő.
* Ez az idő magában foglalja az összes fájlfüggőség importálását is.
*/
collectDuration?: number;
/**
* A beállítási fájl importálásához szükséges idő.
*/
setupDuration?: number;
}
Minden csomagnak van egy tasks
tulajdonsága, amely a gyűjtési fázisban kerül feltöltésre. Ez hasznos a feladatfa felülről lefelé történő bejárásához.
interface Suite extends TaskBase {
type: 'suite';
/**
* Fájl feladat. Ez a fájl gyökérfeladata.
*/
file: File;
/**
* A csomag részét képező feladatok tömbje.
*/
tasks: Task[];
}
Minden feladatnak van egy suite
tulajdonsága, amely arra a csomagra hivatkozik, amelynek része. Ha a test
vagy describe
a legfelső szinten jön létre, akkor nem lesz suite
tulajdonságuk (nem lesz egyenlő a file
-val!). A File
soha nem tartalmaz suite
tulajdonságot. Ez hasznos a feladatok alulról felfelé történő bejárásához.
interface Test<ExtraContext = object> extends TaskBase {
type: 'test';
/**
* Tesztkontextus, amelyet a tesztfüggvénynek adunk át.
*/
context: TestContext & ExtraContext;
/**
* Fájl feladat. Ez a fájl gyökérfeladata.
*/
file: File;
/**
* Jelzi, hogy a feladatot kihagyták-e a `context.skip()` meghívásával.
*/
pending?: boolean;
/**
* Jelzi, hogy a feladatnak sikeresnek kell-e lennie, ha hibát jelez. Ha a feladat hibát jelez, sikeresként lesz megjelölve.
*/
fails?: boolean;
/**
* Ígéretek (aszinkron elvárásokból) tárolása, amelyeket meg kell várni a teszt befejezése előtt.
*/
promises?: Promise<any>[];
}
Minden feladat tartalmazhat result
mezőt. A csomagoknak csak akkor lehet ez a mezője, ha egy hiba a csomag visszahívásában vagy a beforeAll
/afterAll
visszahívásokban megakadályozza a tesztek gyűjtését. A tesztek mindig tartalmazzák ezt a mezőt a visszahívásaik meghívása után – az state
és errors
mezők az eredménytől függően jelennek meg. Ha hiba történt a beforeEach
vagy afterEach
visszahívásokban, a kiváltott hiba a task.result.errors
mezőben található.
export interface TaskResult {
/**
* A feladat állapota. A gyűjtés során átveszi a `task.mode` értékét.
* Amikor a feladat befejeződött, `pass` vagy `fail` értékre vált.
* - **pass**: a feladat sikeresen lefutott
* - **fail**: a feladat sikertelen volt
*/
state: TaskState;
/**
* A feladat végrehajtása során előforduló hibák. Lehetséges több hiba is,
* ha az `expect.soft()` többször is hibát jelzett.
*/
errors?: ErrorWithDiff[];
/**
* A feladat futtatásának ideje milliszekundumban.
*/
duration?: number;
/**
* A feladat futtatásának kezdési ideje milliszekundumban.
*/
startTime?: number;
/**
* A heap mérete bájtban a feladat befejezése után.
* Csak akkor érhető el, ha a `logHeapUsage` opció aktív, és a `process.memoryUsage` definiálva van.
*/
heap?: number;
/**
* Az ehhez a feladathoz tartozó hookok állapota. Hasznos a jelentéskészítés során.
*/
hooks?: Partial<
Record<'afterAll' | 'beforeAll' | 'beforeEach' | 'afterEach', TaskState>
>;
/**
* A feladat újrapróbálkozásainak száma. A feladatot csak akkor próbálják újra, ha
* sikertelen volt, és a `retry` opció be van állítva.
*/
retryCount?: number;
/**
* A feladat ismétléseinek száma. A feladatot csak akkor ismétlik meg, ha
* a `repeats` opció be van állítva. Ez a szám tartalmazza a `retryCount` értéket is.
*/
repeatCount?: number;
}
Saját feladatfüggvény létrehozása
A Vitest createTaskCollector
segédprogramot biztosít a saját test
metódus létrehozásához. Ugyanúgy viselkedik, mint egy teszt, de egy egyedi metódust futtat a gyűjtés során.
A feladat egy objektum, amely egy csomaghoz tartozik. A suite.task
metódussal automatikusan hozzáadódik az aktuális csomaghoz:
import { createTaskCollector, getCurrentSuite } from 'vitest/suite';
export { afterAll, beforeAll, describe } from 'vitest';
// ez a függvény a gyűjtési fázisban hívódik meg:
// ne hívja meg itt a függvénykezelőt, hanem adja hozzá a csomagfeladatokhoz
// a "getCurrentSuite().task()" metódussal
// megjegyzés: a createTaskCollector támogatja a "todo"/"each"/... funkciókat
export const myCustomTask = createTaskCollector(function (name, fn, timeout) {
getCurrentSuite().task(name, {
...this, // így a "todo"/"skip"/... helyesen nyomon követhető
meta: {
customPropertyToDifferentiateTask: true,
},
handler: fn,
timeout,
});
});
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