Tesztfuttató
WARNING
Ez egy fejlett API. Ha csak teszteket szeretne futtatni, valószínűleg nincs szüksége erre. Elsősorban könyvtárfejlesztők használják.
A runner
opcióval megadhatja a tesztfuttató útvonalát a konfigurációs fájlban. Ennek a fájlnak rendelkeznie kell egy alapértelmezett exporttal, amely egy osztálykonstruktort tartalmaz, és implementálja a következő metódusokat:
export interface VitestRunner {
/**
* Az első függvény, ami meghívódik, mielőtt valóban összegyűjtené és futtatná a teszteket.
*/
onBeforeCollect?: (paths: string[]) => unknown;
/**
* A tesztek összegyűjtése után és az "onBeforeRun" metódus 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 a teszteket és csomagokat kihagyottként kell megjelölniük az
* "onBeforeRunSuite" és "onBeforeRunTask" metódusokban, amikor az `onCancel` metódus meghívódik.
*/
onCancel?: (reason: CancelReason) => unknown;
/**
* Egyetlen teszt futtatása előtt hívódik meg. Még nincs `result` mezője.
*/
onBeforeRunTest?: (test: TaskPopulated) => unknown;
/**
* A tesztfüggvény ténylegesen futtatása előtt hívódik meg. Már rendelkezik `result` mezővel, benne `state` és `startTime` értékekkel.
*/
onBeforeTryTask?: (
test: TaskPopulated,
options: { retry: number; repeats: number }
) => unknown;
/**
* Az eredmény és az állapot beállítása után hívódik meg.
*/
onAfterRunTask?: (test: TaskPopulated) => unknown;
/**
* Azonnal a tesztfüggvény futtatása után hívódik meg. Még nincs új állapot. 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. Még nincs `result` mezője.
*/
onBeforeRunSuite?: (suite: Suite) => unknown;
/**
* Egyetlen csomag futtatása után hívódik meg. Rendelkezik állapottal és eredménnyel.
*/
onAfterRunSuite?: (suite: Suite) => unknown;
/**
* Ha definiálva van, a szokásos Vitest csomag felbontás és kezelés helyett hívódik meg.
* A `before` és `after` hookok nem lesznek figyelmen kívül hagyva.
*/
runSuite?: (suite: Suite) => Promise<void>;
/**
* Ha definiálva van, a szokásos Vitest kezelés helyett hívódik meg. Hasznos lehet, ha saját tesztfüggvénye van.
* A `before` és `after` hookok nem lesznek figyelmen kívül hagyva.
*/
runTask?: (test: TaskPopulated) => Promise<void>;
/**
* Akkor hívódik meg, amikor egy feladat frissítésre kerül. Ugyanaz, mint a `onTaskUpdate` egy riporterben, de ez ugyanazon a szálon fut, mint a tesztek.
*/
onTaskUpdate?: (task: [string, TaskResult | undefined][]) => Promise<void>;
/**
* Az összes teszt futtatása előtt hívódik meg az összegyűjtött útvonalakon.
*/
onBeforeRunFiles?: (files: File[]) => unknown;
/**
* Közvetlenül az összes teszt futtatása után hívódik meg az összegyűjtött útvonalakon.
*/
onAfterRunFiles?: (files: File[]) => unknown;
/**
* Akkor hívódik meg, amikor új kontextus van definiálva egy teszthez. Hasznos, ha egyéni tulajdonságokat szeretne hozzáadni a kontextushoz.
* Ha csak egyéni kontextust szeretne definiálni egy futtatóval, fontolja meg a `beforeAll` használatát a `setupFiles`-ban.
*
* Ez a metódus mind a `test`, mind a `custom` kezelőkhöz meghívódik.
*
* @see https://www.getbook.com/en/book/vitest-2/advanced/runner#your-task-function
*/
extendTaskContext?: <T extends Test | Custom>(
context: TaskContext<T>
) => TaskContext<T>;
/**
* Akkor hívódik meg, amikor bizonyos fájlok importálódnak. Két esetben hívódhat meg: tesztek gyűjtésekor és setup fájlok importálásakor.
*/
importFile: (filepath: string, source: VitestRunnerImportSource) => unknown;
/**
* Nyilvánosan elérhető konfiguráció.
*/
config: VitestRunnerConfig;
}
Az osztály inicializálásakor a Vitest átadja a Vitest konfigurációt - ezt config
tulajdonságként kell elérhetővé tennie.
WARNING
A Vitest egy ViteNodeRunner
példányt is injektál __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
elérhetővé teszi az executeId
metódust, amelyet a tesztfájlok importálására használnak Vite-barát környezetben. Ez azt jelenti, hogy futásidőben feloldja az importokat és átalakítja a fájl tartalmát, hogy a Node megértse.
TIP
A snapshot 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
modulból importált VitestTestRunner
-ből. A BenchmarkNodeRunner
-t is elérhetővé teszi, ha a benchmark funkcionalitást szeretné kiterjeszteni.
Feladatok
A csomagokat és teszteket belsőleg tasks
-nak nevezzük. A Vitest futtató egy File
feladatot inicializál, mielőtt bármilyen tesztet gyűjtene - ez egy Suite
feladatnak egy kibővített változata néhány további tulajdonsággal. Minden feladaton (beleértve a File
-t is) elérhető file
tulajdonságként.
interface File extends Suite {
/**
* A pool neve, amelyhez a fájl tartozik.
* @default 'forks'
*/
pool?: string;
/**
* A fájl útvonala UNIX formátumban.
*/
filepath: string;
/**
* A munkaterület projekt neve, amelyhez a fájl tartozik.
*/
projectName: string | undefined;
/**
* Az összes teszt összegyűjtéséhez szükséges idő a fájlban.
* Ez az idő magában foglalja az összes fájlfüggőség importálását is.
*/
collectDuration?: number;
/**
* A beállító fájl importálásához szükséges idő.
*/
setupDuration?: number;
/**
* Azt jelzi, hogy a fájl inicializálva van-e tesztek futtatása nélkül.
* Ezt a Vitest a szerveroldali állapot feltöltésére használja.
*/
local?: boolean;
}
Minden csomagnak van egy tasks
tulajdonsága, amely a gyűjtési fázisban töltődik fel. Hasznos a feladatfa bejárására felülről lefelé.
interface Suite extends TaskBase {
type: 'suite';
/**
* Fájl feladat. Ez a fájl gyökér feladata.
*/
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, amelyben található. Ha a test
vagy describe
a legfelső szinten inicializálódik, nem lesz suite
tulajdonságuk (ez nem lesz egyenlő a file
-lal!). A File
-nak soha nincs suite
tulajdonsága. Hasznos a feladatok bejárására alulról felfelé.
interface Test<ExtraContext = object> extends TaskBase {
type: 'test';
/**
* Teszt kontextus, amely átadásra kerül a tesztfüggvénynek.
*/
context: TaskContext<Test> & ExtraContext & TestContext;
/**
* Fájl feladat. Ez a fájl gyökér feladata.
*/
file: File;
/**
* Azt jelzi, hogy a feladatot kihagyták-e a `t.skip()` hívásával.
*/
pending?: boolean;
/**
* Azt jelzi, hogy a feladatnak sikeresnek kell lennie, ha meghiúsul. Ha a feladat meghiúsul, sikeresként lesz megjelölve.
*/
fails?: boolean;
/**
* Hookok, amelyek futnak, ha a feladat meghiúsul. A sorrend a `sequence.hooks` opciótól függ.
*/
onFailed?: OnTestFailedHandler[];
/**
* Hookok, amelyek futnak, miután a feladat befejeződött. A sorrend a `sequence.hooks` opciótól függ.
*/
onFinished?: OnTestFinishedHandler[];
/**
* Tárolja a promise-okat (aszinkron expect-ekből), hogy megvárja őket a teszt befejezése előtt.
*/
promises?: Promise<any>[];
}
Minden feladatnak lehet egy result
mezője. A csomagoknak csak akkor lehet ez a mezőjük, ha egy hiba dobódik egy csomag visszahívásban vagy beforeAll
/afterAll
visszahívásokban, ami megakadályozza a tesztek gyűjtését. A teszteknek mindig van ez a mezőjük, miután a visszahívásaik meghívódtak - az state
és errors
mezők az eredménytől függően jelennek meg. Ha hiba dobódott a beforeEach
vagy afterEach
visszahívásokban, a dobott hiba jelen lesz a task.result.errors
mezőben.
export interface TaskResult {
/**
* A feladat állapota. Örökli a `task.mode` értékét a gyűjtés során.
* Amikor a feladat befejeződött, `pass` vagy `fail` értékre változik.
* - **pass**: a feladat sikeresen lefutott
* - **fail**: a feladat meghiúsult
*/
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 meghiúsult.
*/
errors?: ErrorWithDiff[];
/**
* Mennyi ideig (ezredmásodpercben) tartott a feladat futása.
*/
duration?: number;
/**
* Az idő (ezredmásodpercben), amikor a feladat futni kezdett.
*/
startTime?: number;
/**
* Heap méret (bájtokban) a feladat befejezése után.
* Csak akkor érhető el, ha a `logHeapUsage` opció be van állítva, és a `process.memoryUsage` definiálva van.
*/
heap?: number;
/**
* A feladathoz kapcsolódó hookok állapota. Hasznos a riportolás során.
*/
hooks?: Partial<
Record<'afterAll' | 'beforeAll' | 'beforeEach' | 'afterEach', TaskState>
>;
/**
* Az újrapróbálkozások száma. A feladatot csak akkor próbálják újra, ha
* meghiúsult, és a `retry` opció be van állítva.
*/
retryCount?: number;
/**
* Ahányszor a feladatot megismételték. A feladatot csak akkor ismétlik meg, ha
* a `repeats` opció be van állítva. Ez a szám tartalmazza a `retryCount`-ot is.
*/
repeatCount?: number;
}
Saját Feladat Függvény
A Vitest elérhetővé tesz egy Custom
feladat típust, amely lehetővé teszi a felhasználók számára a beépített riporterek újrahasználatát. Lényegében ugyanaz, mint a Test
, de a típusa 'custom'
.
Egy feladat egy objektum, amely egy csomag része. Automatikusan hozzáadódik az aktuális csomaghoz a suite.task
metódussal:
// ./utils/custom.js
import { createTaskCollector, getCurrentSuite, setFn } 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ény kezelőt, adja hozzá a csomag feladataihoz
// a `getCurrentSuite().task()` metódussal
// megjegyzés: a `createTaskCollector` támogatást nyújt a `todo`/`each`/... számára
export const myCustomTask = createTaskCollector(function (name, fn, timeout) {
getCurrentSuite().task(name, {
...this, // így a `todo`/`skip`/... helyesen követhető
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
Ha nincs egyéni futtatója, vagy nem definiálta a runTest
metódust, a Vitest megpróbálja automatikusan lekérni a feladatot. Ha nem adott hozzá függvényt a setFn
-nel, akkor sikertelen lesz.