Referenční příručka k Test API
Následující typy se používají v typových podpisech níže
type Awaitable<T> = T | PromiseLike<T>;
type TestFunction = () => Awaitable<void>;
interface TestOptions {
/**
* Test selže, pokud jeho provedení trvá příliš dlouho.
*/
timeout?: number;
/**
* Pokud test selže, provede se tolikrát, kolikrát je uvedeno.
*
* @default 0
*/
retry?: number;
/**
* Stejný test se opakuje několikrát, i když opakovaně selže.
* Pokud máte možnost "retry" a test selže, použije každé opakování v každém cyklu.
* Užitečné pro odhalování náhodných selhání.
*
* @default 0
*/
repeats?: number;
}Když testovací funkce vrací promise (objekt pro asynchronní operace), spouštěč testů počká, dokud se promise nevyřeší, aby shromáždil asynchronní očekávání. Pokud je promise odmítnut, test selže.
TIP
V Jest může být TestFunction také typu (done: DoneCallback) => void. Pokud je tento způsob použit, test nebude ukončen, dokud nebude zavolána funkce done. Stejného výsledku můžete dosáhnout pomocí funkce async, viz Průvodce migrací, sekce Done Callback.
test
Typ:
(name: string | Function, fn: TestFunction, timeout?: number | TestOptions) => voidAlias:
ittestdefinuje sadu souvisejících očekávání. Přijímá název testu a funkci, která obsahuje očekávání, která se mají ověřit.Můžete volitelně zadat timeout (v milisekundách), abyste určili, jak dlouho čekat před ukončením testu. Výchozí hodnota je 5 sekund a lze ji globálně nastavit pomocí testTimeout.
tsimport { expect, test } from 'vitest'; test('should work as expected', () => { expect(Math.sqrt(4)).toBe(2); });
test.extend
Typ:
<T extends Record<string, any>>(fixtures: Fixtures<T>): TestAPI<ExtraContext & T>Alias:
it.extendVerze: Vitest 0.32.3
Pomocí
test.extendmůžete rozšířit testovací kontext o vlastní přípravky (fixtures). Tím se vrátí novýtest, který je také rozšiřitelný, takže můžete skládat další přípravky nebo přepsat stávající rozšířením podle potřeby. Další informace naleznete v Rozšíření testovacího kontextu.tsimport { expect, test } from 'vitest'; const todos = []; const archive = []; const myTest = test.extend({ todos: async ({ task }, use) => { todos.push(1, 2, 3); await use(todos); todos.length = 0; }, archive, }); myTest('add item', ({ todos }) => { expect(todos.length).toBe(3); todos.push(4); expect(todos.length).toBe(4); });
test.skip
Typ:
(name: string | Function, fn: TestFunction, timeout?: number | TestOptions) => voidAlias:
it.skipPokud chcete přeskočit provádění některých testů, ale nechcete smazat jejich kód, použijte
test.skip.tsimport { assert, test } from 'vitest'; test.skip('skipped test', () => { // Test skipped, no error assert.equal(Math.sqrt(4), 3); });Test můžete také přeskočit dynamicky voláním
skipna jeho kontextu:tsimport { assert, test } from 'vitest'; test('skipped test', context => { context.skip(); // Test skipped, no error assert.equal(Math.sqrt(4), 3); });
test.skipIf
Typ:
(condition: any) => TestAlias:
it.skipIfV některých případech se testy spouští opakovaně v různých prostředích, přičemž některé testy jsou specifické pro dané prostředí. Místo použití
ifpro obalení testovacího kódu můžete použíttest.skipIfpro přeskočení testu, pokud je daná podmínka splněna.tsimport { assert, test } from 'vitest'; const isDev = process.env.NODE_ENV === 'development'; test.skipIf(isDev)('prod only test', () => { // this test only runs in production });
WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
test.runIf
Typ:
(condition: any) => TestAlias:
it.runIfOpak test.skipIf.
tsimport { assert, test } from 'vitest'; const isDev = process.env.NODE_ENV === 'development'; test.runIf(isDev)('dev only test', () => { // this test only runs in development });
WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
test.only
Typ:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.onlyPoužijte
test.only, abyste spustili pouze určité testy v dané sadě. To je užitečné při ladění.Můžete volitelně zadat timeout (v milisekundách), abyste určili, jak dlouho čekat před ukončením testu. Výchozí hodnota je 5 sekund a lze ji globálně nastavit pomocí testTimeout.
tsimport { assert, test } from 'vitest'; test.only('test', () => { // Only this test (and others marked with only) are run assert.equal(Math.sqrt(4), 2); });Někdy je velmi užitečné spouštět testy označené
onlyv určitém souboru a ignorovat všechny ostatní testy z celé testovací sady, které znečišťují výstup.Chcete-li to provést, spusťte
vitestse specifickým souborem obsahujícím dotyčné testy.# vitest interesting.test.ts
test.concurrent
Typ:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.concurrenttest.concurrentoznačuje testy, které se mají spouštět paralelně. Přijímá název testu, asynchronní funkci s testy a volitelný timeout (v milisekundách).tsimport { describe, test } from 'vitest'; // The two tests marked with concurrent will be run in parallel describe('suite', () => { test('serial test', async () => { /* ... */ }); test.concurrent('concurrent test 1', async () => { /* ... */ }); test.concurrent('concurrent test 2', async () => { /* ... */ }); });test.skip,test.onlyatest.todofungují s concurrent testy. Všechny následující kombinace jsou platné:tstest.concurrent(/* ... */); test.skip.concurrent(/* ... */); // or test.concurrent.skip(/* ... */) test.only.concurrent(/* ... */); // or test.concurrent.only(/* ... */) test.todo.concurrent(/* ... */); // or test.concurrent.todo(/* ... */)Při provádění paralelních testů musí snímky (snapshots) a tvrzení (assertions) používat
expectz místního Test Context, aby bylo zajištěno, že je detekován správný test.tstest.concurrent('test 1', async ({ expect }) => { expect(foo).toMatchSnapshot(); }); test.concurrent('test 2', async ({ expect }) => { expect(foo).toMatchSnapshot(); });
WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
test.todo
Typ:
(name: string | Function) => voidAlias:
it.todoPoužijte
test.todok vytvoření zástupných testů, které budou implementovány později. V sestavě se zobrazí záznam pro tyto testy, abyste věděli, kolik testů ještě musíte implementovat.ts// An entry will be shown in the report for this test test.todo('unimplemented test');
test.fails
Typ:
(name: string | Function, fn: TestFunction, timeout?: number) => voidAlias:
it.failsPomocí
test.failsoznačíte, že dané tvrzení má selhat.tsimport { expect, test } from 'vitest'; function myAsyncFunc() { return new Promise(resolve => resolve(1)); } test.fails('fail test', async () => { await expect(myAsyncFunc()).rejects.toBe(1); });
WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
test.each
Typ:
(cases: ReadonlyArray<T>, ...args: any[]) => voidAlias:
it.eachPoužijte
test.each, když potřebujete spustit stejný test s různými proměnnými. Parametry můžete vložit pomocí printf formatting v názvu testu v pořadí parametrů testovací funkce.%s: string%d: number%i: integer%f: floating point value%j: json%o: object%#: index of the test case%%: single percent sign ('%')
tstest.each([ [1, 1, 2], [1, 2, 3], [2, 1, 3], ])('add(%i, %i) -> %i', (a, b, expected) => { expect(a + b).toBe(expected); }); // this will return // ✓ add(1, 1) -> 2 // ✓ add(1, 2) -> 3 // ✓ add(2, 1) -> 3Můžete také přistupovat k vlastnostem objektu pomocí předpony
$, pokud používáte objekty jako argumenty:tstest.each([ { a: 1, b: 1, expected: 2 }, { a: 1, b: 2, expected: 3 }, { a: 2, b: 1, expected: 3 }, ])('add($a, $b) -> $expected', ({ a, b, expected }) => { expect(a + b).toBe(expected); }); // this will return // ✓ add(1, 1) -> 2 // ✓ add(1, 2) -> 3 // ✓ add(2, 1) -> 3Můžete také přistupovat k atributům objektu pomocí
., pokud používáte objekty jako argumenty:tstest.each` a | b | expected ${{ val: 1 }} | ${'b'} | ${'1b'} ${{ val: 2 }} | ${'b'} | ${'2b'} ${{ val: 3 }} | ${'b'} | ${'3b'} `('add($a.val, $b) -> $expected', ({ a, b, expected }) => { expect(a.val + b).toBe(expected); }); // this will return // ✓ add(1, b) -> 1b // ✓ add(2, b) -> 2b // ✓ add(3, b) -> 3bPočínaje Vitest 0.25.3 můžete také použít tabulku šablonových řetězců.
- První řádek by měl obsahovat názvy sloupců oddělené znakem
|; - Jeden nebo více následujících řádků dat zadaných jako template literal expressions pomocí syntaxe
${value}.
tstest.each` a | b | expected ${1} | ${1} | ${2} ${'a'} | ${'b'} | ${'ab'} ${[]} | ${'b'} | ${'b'} ${{}} | ${'b'} | ${'[object Object]b'} ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'} `('returns $expected when $a is added $b', ({ a, b, expected }) => { expect(a + b).toBe(expected); });Pokud chcete mít přístup k
TestContext, použijtedescribe.eachs jedním testem.
TIP
Vitest zpracovává $values pomocí metody format knihovny Chai. Pokud je hodnota příliš zkrácena, můžete zvýšit chaiConfig.truncateThreshold v konfiguračním souboru.
WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
bench
- Typ:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
bench definuje benchmark. V kontextu Vitest je benchmark funkce definující sérii operací. Vitest tuto funkci spouští opakovaně, aby zobrazil různé výsledky výkonu.
Vitest interně využívá knihovnu tinybench a přebírá všechny její možnosti, které lze použít jako třetí argument.
import { bench } from 'vitest';
bench(
'normal sorting',
() => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
},
{ time: 1000 }
);export interface Options {
/**
* Čas potřebný pro spuštění benchmark úlohy (milisekundy).
* @default 500
*/
time?: number;
/**
* Počet opakování, kolikrát by se měla úloha spustit, i když je časová možnost dokončena.
* @default 10
*/
iterations?: number;
/**
* Funkce pro získání aktuálního timestamp v milisekundách.
*/
now?: () => number;
/**
* An AbortSignal for aborting the benchmark
*/
signal?: AbortSignal;
/**
* Warmup time (milisekundy).
* @default 100ms
*/
warmupTime?: number;
/**
* Warmup iterations.
* @default 5
*/
warmupIterations?: number;
/**
* Setup hook funkce, která se spustí před každou benchmark úlohou (cyklem).
*/
setup?: Hook;
/**
* Teardown hook funkce, která se spustí po každé benchmark úloze (cyklu).
*/
teardown?: Hook;
}bench.skip
- Typ:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Pro přeskočení spouštění určitých benchmarků můžete použít syntaxi bench.skip.
import { bench } from 'vitest';
bench.skip('normal sorting', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});bench.only
- Typ:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Pomocí bench.only spustíte pouze vybrané benchmarky v dané sadě. To je užitečné při ladění.
import { bench } from 'vitest';
bench.only('normal sorting', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});bench.todo
- Typ:
(name: string | Function) => void
Pomocí bench.todo vytvoříte stubs (zástupné benchmarky) pro pozdější implementaci.
import { bench } from 'vitest';
bench.todo('unimplemented test');describe
Pokud použijete test nebo bench na nejvyšší úrovni souboru, jsou tyto funkce zahrnuty jako součást implicitní sady testů. Pomocí describe můžete definovat novou sadu v aktuálním kontextu, například sadu souvisejících testů, benchmarků nebo dalších vnořených sad. Sada umožňuje uspořádat testy a benchmarky, čímž jsou výstupy přehlednější.
// basic.spec.ts
// organizace testů
import { describe, expect, test } from 'vitest';
const person = {
isActive: true,
age: 32,
};
describe('person', () => {
test('person is defined', () => {
expect(person).toBeDefined();
});
test('is active', () => {
expect(person.isActive).toBeTruthy();
});
test('age limit', () => {
expect(person.age).toBeLessThanOrEqual(32);
});
});// basic.bench.ts
// organizace benchmarků
import { bench, describe } from 'vitest';
describe('sort', () => {
bench('normal', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});
bench('reverse', () => {
const x = [1, 5, 4, 2, 3];
x.reverse().sort((a, b) => {
return a - b;
});
});
});Můžete také vnořovat bloky describe, pokud máte hierarchickou strukturu testů nebo benchmarků:
import { describe, expect, test } from 'vitest';
function numberToCurrency(value) {
if (typeof value !== 'number') throw new Error('Value must be a number');
return value
.toFixed(2)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
describe('numberToCurrency', () => {
describe('pokud je zadáno neplatné číslo', () => {
test('pokud obsahuje nečíselné hodnoty, vyhodí chybu', () => {
expect(() => numberToCurrency('abc')).toThrowError();
});
});
describe('pokud je zadáno platné číslo', () => {
test('vrací správný formát měny', () => {
expect(numberToCurrency(10000)).toBe('10,000.00');
});
});
});describe.skip
Typ:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidPoužijte
describe.skippro přeskočení konkrétního blokudescribe.tsimport { assert, describe, test } from 'vitest'; describe.skip('skipped suite', () => { test('sqrt', () => { // Sada je přeskočena, žádná chyba assert.equal(Math.sqrt(4), 3); }); });
describe.skipIf
Typ:
(condition: any) => voidV některých případech může být potřeba spouštět testovací sady v různých prostředích a některé sady mohou být specifické pro dané prostředí. Místo použití
ifpro obalení sady můžete použítdescribe.skipIfk jejímu přeskočení, pokud je daná podmínka splněna (truthy).tsimport { describe, test } from 'vitest'; const isDev = process.env.NODE_ENV === 'development'; describe.skipIf(isDev)('prod only test', () => { // tento test se spouští pouze v produkci });
WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
describe.only
Typ:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidPoužijte
describe.onlyke spuštění pouze určitých sad.ts// Spustí se pouze tato sada (a další označené jako only) describe.only('suite', () => { test('sqrt', () => { assert.equal(Math.sqrt(4), 3); }); }); describe('other suite', () => { // ... bude přeskočeno });Někdy je velmi užitečné spouštět testy
onlyv určitém souboru a ignorovat všechny ostatní testy, které znečišťují výstup.Chcete-li to provést, spusťte
vitests konkrétním souborem obsahujícím příslušné testy.# vitest interesting.test.ts
describe.concurrent
Typ:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voiddescribe.concurrentoznačuje všechny testy v sadě jako souběžné (paralelní).ts// Všechny testy v této sadě budou spuštěny paralelně describe.concurrent('suite', () => { test('concurrent test 1', async () => { /* ... */ }); test('concurrent test 2', async () => { /* ... */ }); test.concurrent('concurrent test 3', async () => { /* ... */ }); });.skip,.onlya.todofungují se souběžnými sadami. Všechny následující kombinace jsou platné:tsdescribe.concurrent(/* ... */); describe.skip.concurrent(/* ... */); // or describe.concurrent.skip(/* ... */) describe.only.concurrent(/* ... */); // or describe.concurrent.only(/* ... */) describe.todo.concurrent(/* ... */); // or describe.concurrent.todo(/* ... */)
Při spouštění souběžných testů musí snímky (Snapshots) a tvrzení (Assertions) používat expect z lokálního Testovacího kontextu, aby bylo zajištěno, že je detekován správný test.
describe.concurrent('suite', () => {
test('concurrent test 1', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
test('concurrent test 2', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
});WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
describe.sequential
Typ:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voiddescribe.sequentialoznačí všechny testy v sadě jako sekvenční. To je užitečné, pokud potřebujete spouštět testy sekvenčně uvnitř blokudescribe.concurrentnebo s použitím volby--sequence.concurrentv příkazovém řádku.tsdescribe.concurrent('suite', () => { test('concurrent test 1', async () => { /* ... */ }); test('concurrent test 2', async () => { /* ... */ }); describe.sequential('', () => { test('sequential test 1', async () => { /* ... */ }); test('sequential test 2', async () => { /* ... */ }); }); });
describe.shuffle
Typ:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => voidVitest umožňuje spouštět testy v náhodném pořadí pomocí příznaku CLI
--sequence.shufflenebo volby konfiguracesequence.shuffle. Pokud chcete v náhodném pořadí spouštět pouze část testovací sady, můžete ji označit tímto příznakem.tsdescribe.shuffle('suite', () => { test('random test 1', async () => { /* ... */ }); test('random test 2', async () => { /* ... */ }); test('random test 3', async () => { /* ... */ }); }); // pořadí závisí na možnosti sequence.seed v konfiguraci (ve výchozím nastavení Date.now())
.skip, .only a .todo fungují s náhodnými sadami.
WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
describe.todo
Typ:
(name: string | Function) => voidPoužijte
describe.todok označení sad, které budou implementovány později, jako zástupné symboly (stuby). Ve zprávě se zobrazí položka pro testy, abyste věděli, kolik testů ještě musíte implementovat.ts// Ve zprávě se zobrazí položka pro tuto sadu describe.todo('unimplemented suite');
describe.each
Typ:
(cases: ReadonlyArray<T>, ...args: any[]): (name: string | Function, fn: (...args: T[]) => void, options?: number | TestOptions) => voidPoužijte
describe.each, pokud máte více než jeden test, který závisí na stejných datech.tsdescribe.each([ { a: 1, b: 1, expected: 2 }, { a: 1, b: 2, expected: 3 }, { a: 2, b: 1, expected: 3 }, ])('describe object add($a, $b)', ({ a, b, expected }) => { test(`returns ${expected}`, () => { expect(a + b).toBe(expected); }); test(`returned value not be greater than ${expected}`, () => { expect(a + b).not.toBeGreaterThan(expected); }); test(`returned value not be less than ${expected}`, () => { expect(a + b).not.toBeLessThan(expected); }); });Počínaje Vitest 0.25.3 můžete také použít tabulku vytvořenou pomocí template literals.
- První řádek by měl obsahovat názvy sloupců oddělené znakem
|; - Jeden nebo více následujících řádků dat zadaných jako výrazy šablonových literálů pomocí syntaxe
${value}.
tsdescribe.each` a | b | expected ${1} | ${1} | ${2} ${'a'} | ${'b'} | ${'ab'} ${[]} | ${'b'} | ${'b'} ${{}} | ${'b'} | ${'[object Object]b'} ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'} `('describe template string add($a, $b)', ({ a, b, expected }) => { test(`returns ${expected}`, () => { expect(a + b).toBe(expected); }); });- První řádek by měl obsahovat názvy sloupců oddělené znakem
WARNING
Tuto syntaxi nemůžete použít, pokud používáte Vitest jako kontrolu typů.
Nastavení a ukončení
Tyto funkce umožňují zasáhnout do životního cyklu testů a vyhnout se tak opakování kódu pro nastavení a ukončení. Platí pro aktuální kontext. Pokud jsou použity na nejvyšší úrovni, vztahují se na celý soubor. Pokud jsou uvnitř bloku describe, platí pouze pro danou sadu. Tyto pomocné funkce nejsou volány, pokud spouštíte Vitest jako kontrolu typů.
beforeEach
Typ:
beforeEach(fn: () => Awaitable<void>, timeout?: number)Zaregistruje funkci, která se má spustit před každým testem v aktuálním kontextu. Pokud funkce vrací promise, Vitest čeká, dokud se promise nevyřeší, než spustí test.
Volitelně můžete předat timeout (v milisekundách) definující, jak dlouho čekat před ukončením. Výchozí hodnota je 5 sekund.
tsimport { beforeEach } from 'vitest'; beforeEach(async () => { // Vymaže imitační data a přidá některá testovací data po spuštění každého testu await stopMocking(); await addUser({ name: 'John' }); });Zde
beforeEachzajišťuje, že uživatel je přidán před každým testem.Od verze Vitest v0.10.0 umožňuje
beforeEachtaké definovat volitelnou úklidovou funkci (ekvivalentníafterEach).tsimport { beforeEach } from 'vitest'; beforeEach(async () => { // voláno jednou před spuštěním každého testu await prepareSomething(); // funkce pro úklid, volána jednou po spuštění každého testu return async () => { await resetSomething(); }; });
afterEach
Typ:
afterEach(fn: () => Awaitable<void>, timeout?: number)Zaregistruje funkci, která se má spustit po každém testu v aktuálním kontextu. Pokud funkce vrací promise, Vitest čeká, dokud se promise nevyřeší, než bude pokračovat.
Volitelně můžete zadat timeout (v milisekundách) pro určení, jak dlouho čekat před ukončením. Výchozí hodnota je 5 sekund.
tsimport { afterEach } from 'vitest'; afterEach(async () => { await clearTestingData(); // vymaže testovací data po spuštění každého testu });Zde
afterEachzajišťuje, že testovací data jsou vymazána po každém testu.
beforeAll
Typ:
beforeAll(fn: () => Awaitable<void>, timeout?: number)Zaregistruje funkci, která se má spustit jednou před spuštěním všech testů v aktuálním kontextu. Pokud funkce vrací promise, Vitest čeká, dokud se promise nevyřeší, než spustí testy.
Volitelně můžete zadat timeout (v milisekundách) pro určení, jak dlouho čekat před ukončením. Výchozí hodnota je 5 sekund.
tsimport { beforeAll } from 'vitest'; beforeAll(async () => { await startMocking(); // voláno jednou před spuštěním všech testů });Zde
beforeAllzajišťuje, že jsou imitační data nastavena před spuštěním testů.Od verze Vitest v0.10.0 umožňuje
beforeAlltaké definovat volitelnou úklidovou funkci (ekvivalentníafterAll).tsimport { beforeAll } from 'vitest'; beforeAll(async () => { // voláno jednou před spuštěním všech testů await startMocking(); // funkce pro úklid, volána jednou po spuštění všech testů return async () => { await stopMocking(); }; });
afterAll
Typ:
afterAll(fn: () => Awaitable<void>, timeout?: number)Zaregistruje funkci, která se má spustit jednou po spuštění všech testů v aktuálním kontextu. Pokud funkce vrací promise, Vitest čeká, dokud se promise nevyřeší, než bude pokračovat.
Volitelně můžete zadat timeout (v milisekundách) pro určení, jak dlouho čekat před ukončením. Výchozí hodnota je 5 sekund.
tsimport { afterAll } from 'vitest'; afterAll(async () => { await stopMocking(); // tato metoda je volána po spuštění všech testů });Zde
afterAllzajišťuje, že metodastopMockingje volána po spuštění všech testů.