Test API Referenz
Die folgenden Typen werden in den Typsignaturen unten verwendet:
type Awaitable<T> = T | PromiseLike<T>;
type TestFunction = () => Awaitable<void>;
interface TestOptions {
/**
* Der Test schlägt fehl, wenn die Ausführung zu lange dauert
*/
timeout?: number;
/**
* Wiederholt den Test eine bestimmte Anzahl von Malen, wenn er fehlschlägt
*
* @default 0
*/
retry?: number;
/**
* Führt denselben Test mehrmals aus, auch wenn er jedes Mal fehlschlägt.
* Wenn die Option "retry" aktiviert ist und der Test fehlschlägt, wird jede Wiederholung in jedem Zyklus verwendet.
* Nützlich für die Fehlersuche bei sporadisch auftretenden Fehlern.
*
* @default 0
*/
repeats?: number;
}Wenn eine Testfunktion eine Promise zurückgibt, wartet der Runner, bis diese aufgelöst ist, um asynchrone Erwartungen zu überprüfen. Wenn die Promise abgewiesen wird, schlägt der Test fehl.
TIP
In Jest kann TestFunction auch vom Typ (done: DoneCallback) => void sein. Wenn diese Form verwendet wird, wird der Test erst abgeschlossen, wenn done aufgerufen wird. Sie können dasselbe mit einer async-Funktion erreichen, siehe den Abschnitt Migration guide Done Callback section.
Die meisten Optionen unterstützen sowohl Punkt-Syntax als auch Objekt-Syntax, so dass Sie den Stil nutzen können, den Sie bevorzugen.
import { test } from 'vitest';
test.skip('skipped test', () => {
// some logic that fails right now
});import { test } from 'vitest';
test('skipped test', { skip: true }, () => {
// some logic that fails right now
});test
- Alias:
it
test definiert eine Testfall mit zugehörigen Erwartungen. Es erwartet den Testnamen und eine Funktion, die die zu testenden Erwartungen enthält.
Optional können Sie ein Timeout (in Millisekunden) angeben, um festzulegen, wie lange auf den Abschluss des Tests gewartet werden soll. Der Standardwert ist 5 Sekunden und kann global mit testTimeout konfiguriert werden.
import { expect, test } from 'vitest';
test('should work as expected', () => {
expect(Math.sqrt(4)).toBe(2);
});test.extend
- Alias:
it.extend
Verwenden Sie test.extend, um den Testkontext mit benutzerdefinierten Fixtures zu erweitern. Dies gibt eine neue test-Funktion zurück, die ebenfalls erweiterbar ist. Sie können weitere Fixtures hinzufügen oder vorhandene überschreiben, indem Sie sie nach Bedarf erweitern. Weitere Informationen finden Sie unter Extend Test Context.
import { 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
- Alias:
it.skip
Wenn Sie bestimmte Tests überspringen möchten, den Code aber aus irgendeinem Grund nicht löschen wollen, können Sie test.skip verwenden, um deren Ausführung zu verhindern.
import { assert, test } from 'vitest';
test.skip('skipped test', () => {
// Test übersprungen, kein Fehler
assert.equal(Math.sqrt(4), 3);
});Sie können einen Test auch überspringen, indem Sie skip dynamisch im Testkontext aufrufen:
import { assert, test } from 'vitest';
test('skipped test', context => {
context.skip();
// Test übersprungen, kein Fehler
assert.equal(Math.sqrt(4), 3);
});test.skipIf
- Alias:
it.skipIf
In manchen Fällen führen Sie möglicherweise Tests mehrmals mit verschiedenen Umgebungen aus, und einige der Tests sind möglicherweise umgebungsspezifisch. Anstatt den Testcode mit if zu umschließen, können Sie test.skipIf verwenden, um den Test zu überspringen, wenn die Bedingung erfüllt ist.
import { assert, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
test.skipIf(isDev)('prod only test', () => {
// dieser Test wird nur in der Produktion ausgeführt
});WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest als Type Checker verwenden.
test.runIf
- Alias:
it.runIf
Gegenteil von test.skipIf.
import { assert, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
test.runIf(isDev)('dev only test', () => {
// dieser Test wird nur in der Entwicklung ausgeführt
});WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest als Type Checker verwenden.
test.only
- Alias:
it.only
Verwenden Sie test.only, um nur bestimmte Tests in einer Testsuite auszuführen. Dies ist beim Debuggen nützlich.
Optional können Sie ein Timeout (in Millisekunden) angeben, um festzulegen, wie lange auf den Abschluss des Tests gewartet werden soll. Der Standardwert ist 5 Sekunden und kann global mit testTimeout konfiguriert werden.
import { assert, test } from 'vitest';
test.only('test', () => {
// Nur dieser Test (und andere, die mit only markiert sind) werden ausgeführt
assert.equal(Math.sqrt(4), 2);
});Manchmal ist es sehr nützlich, only-Tests in einer bestimmten Datei auszuführen und alle anderen Tests aus der gesamten Testsuite zu ignorieren, die die Ausgabe beeinträchtigen.
Führen Sie dazu vitest mit der spezifischen Datei aus, die die betreffenden Tests enthält.
# vitest interesting.test.tstest.concurrent
- Alias:
it.concurrent
test.concurrent kennzeichnet Tests, die parallel ausgeführt werden sollen. Es erwartet den Testnamen, eine asynchrone Funktion mit den zu überprüfenden Tests und ein optionales Timeout (in Millisekunden).
import { describe, test } from 'vitest';
// Die beiden mit concurrent markierten Tests werden parallel ausgeführt
describe('suite', () => {
test('serial test', async () => {
/* ... */
});
test.concurrent('concurrent test 1', async () => {
/* ... */
});
test.concurrent('concurrent test 2', async () => {
/* ... */
});
});test.skip, test.only und test.todo funktionieren mit Concurrent-Tests. Alle folgenden Kombinationen sind gültig:
test.concurrent(/* ... */);
test.skip.concurrent(/* ... */); // or test.concurrent.skip(/* ... */)
test.only.concurrent(/* ... */); // or test.concurrent.only(/* ... */)
test.todo.concurrent(/* ... */); // or test.concurrent.todo(/* ... */)Beim Ausführen von Concurrent-Tests müssen Snapshots und Assertions expect aus dem lokalen Test Context verwenden, um sicherzustellen, dass der richtige Test erkannt wird.
test.concurrent('test 1', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
test.concurrent('test 2', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest als Type Checker verwenden.
test.sequential
- Alias:
it.sequential
test.sequential markiert einen Test als sequenziell. Dies ist nützlich, wenn Sie Tests innerhalb von describe.concurrent oder mit der Befehlszeilenoption --sequence.concurrent sequenziell ausführen möchten.
import { describe, test } from 'vitest';
// mit der Konfigurationsoption { sequence: { concurrent: true } }
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
test.sequential('sequential test 1', async () => {
/* ... */
});
test.sequential('sequential test 2', async () => {
/* ... */
});
// innerhalb einer nebenläufigen Suite
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
test('concurrent test 2', async () => {
/* ... */
});
test.sequential('sequential test 1', async () => {
/* ... */
});
test.sequential('sequential test 2', async () => {
/* ... */
});
});test.todo
- Alias:
it.todo
Verwenden Sie test.todo, um Tests zu kennzeichnen, die später implementiert werden sollen. Der Bericht zeigt einen Eintrag für jeden dieser Tests an, sodass Sie einen Überblick über die noch zu implementierenden Tests haben.
// Für diesen Test wird ein Eintrag im Bericht angezeigt
test.todo('unimplemented test');test.fails
- Alias:
it.fails
Verwenden Sie test.fails, um anzuzeigen, dass eine Assertion bewusst fehlschlagen soll.
import { expect, test } from 'vitest';
function myAsyncFunc() {
return new Promise(resolve => resolve(1));
}
test.fails('fail test', async () => {
await expect(myAsyncFunc()).rejects.toBe(1);
});WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest als Type Checker verwenden.
test.each
- Alias:
it.each
TIP
Während test.each zur Jest-Kompatibilität bereitgestellt wird, bietet Vitest auch test.for mit einer zusätzlichen Funktion zur Integration von TestContext.
Verwenden Sie test.each, wenn Sie denselben Test mit verschiedenen Variablen ausführen müssen. Sie können Parameter mit printf formatting im Testnamen in der Reihenfolge der Testfunktionsparameter einfügen.
%s: string%d: number%i: integer%f: floating point value%j: json%o: object%#: index of the test case%%: single percent sign ('%')
import { expect, test } from 'vitest';
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
expect(a + b).toBe(expected);
});
// dies wird zurückgeben
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3Sie können auch mit dem Präfix $ auf Objekteigenschaften zugreifen, wenn Sie Objekte als Argumente verwenden:
test.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);
});
// dies wird zurückgeben
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3Sie können auch mit . auf Objektattribute zugreifen, wenn Sie Objekte als Argumente verwenden:
test.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);
});
// dies wird zurückgeben
// ✓ add(1, b) -> 1b
// ✓ add(2, b) -> 2b
// ✓ add(3, b) -> 3bAb Vitest 0.25.3 können Sie auch eine Template-String-Tabelle verwenden.
- Die erste Zeile sollte aus Spaltennamen bestehen, die durch
|getrennt sind; - Eine oder mehrere nachfolgende Datenzeilen, die als Template-Literal-Ausdrücke mit der Syntax
${value}bereitgestellt werden.
import { expect, test } from 'vitest';
test.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);
});TIP
Vitest verarbeitet $values mit der Chai format-Methode. Wenn der Wert zu stark abgeschnitten ist, können Sie chaiConfig.truncateThreshold in Ihrer Konfigurationsdatei erhöhen.
WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest als Type Checker verwenden.
test.for
- Alias:
it.for
Alternative zu test.each, um TestContext bereitzustellen.
Der Unterschied zu test.each ist, wie der Array-Fall in den Argumenten übergeben wird. Andere Fälle, die keine Arrays sind (einschließlich der Verwendung von Template-Strings), funktionieren genau gleich.
// `each` spreizt den Array-Fall
test.each([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
expect(a + b).toBe(expected);
});
// `for` spreizt den Array-Fall nicht
test.for([
[1, 1, 2],
[1, 2, 3],
[2, 1, 3],
])('add(%i, %i) -> %i', ([a, b, expected]) => {
expect(a + b).toBe(expected);
});Das 2. Argument ist TestContext und kann beispielsweise für gleichzeitige Snapshots verwendet werden:
test.concurrent.for([
[1, 1],
[1, 2],
[2, 1],
])('add(%i, %i)', ([a, b], { expect }) => {
expect(a + b).matchSnapshot();
});bench
- Typ:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
bench definiert einen Benchmark. In Vitest-Begriffen ist ein Benchmark eine Funktion, die eine Reihe von Operationen definiert. Vitest führt diese Funktion mehrmals im Hintergrund aus, um verschiedene Leistungsergebnisse anzuzeigen.
Vitest verwendet im Hintergrund die Bibliothek tinybench und übernimmt alle zugehörigen Optionen, die als drittes Argument übergeben werden können.
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 {
/**
* Zeit, die für die Ausführung einer Benchmark-Aufgabe benötigt wird (Millisekunden)
* @default 500
*/
time?: number;
/**
* Anzahl der Ausführungen einer Aufgabe, auch wenn die Zeitoption beendet ist
* @default 10
*/
iterations?: number;
/**
* Funktion, um den aktuellen Zeitstempel in Millisekunden abzurufen
*/
now?: () => number;
/**
* Ein AbortSignal zum Abbrechen des Benchmarks
*/
signal?: AbortSignal;
/**
* Löst einen Fehler aus, wenn eine Aufgabe fehlschlägt (Ereignisse funktionieren nicht, wenn wahr)
*/
throws?: boolean;
/**
* Aufwärmzeit (Millisekunden)
* @default 100ms
*/
warmupTime?: number;
/**
* Aufwärmdurchläufe
* @default 5
*/
warmupIterations?: number;
/**
* Setup-Funktion, die vor jeder Benchmark-Aufgabe (Zyklus) ausgeführt wird
*/
setup?: Hook;
/**
* Teardown-Funktion, die nach jeder Benchmark-Aufgabe (Zyklus) ausgeführt wird
*/
teardown?: Hook;
}Nachdem der Testfall ausgeführt wurde, sind die Informationen zur Ausgabestruktur wie folgt:
name hz min max mean p75 p99 p995 p999 rme samples
· normal sorting 6,526,368.12 0.0001 0.3638 0.0002 0.0002 0.0002 0.0002 0.0004 ±1.41% 652638export interface TaskResult {
/*
* der letzte Fehler, der während der Ausführung der Aufgabe geworfen wurde
*/
error?: unknown;
/**
* Die Zeit in Millisekunden, die für die Ausführung der Benchmark-Aufgabe (Zyklus) benötigt wird.
*/
totalTime: number;
/**
* der minimale Wert in den Stichproben
*/
min: number;
/**
* der maximale Wert in den Stichproben
*/
max: number;
/**
* die Anzahl der Operationen pro Sekunde
*/
hz: number;
/**
* wie lange jede Operation dauert (ms)
*/
period: number;
/**
* Aufgabenstichproben der Zeit für jede Aufgabeniteration (ms)
*/
samples: number[];
/**
* Mittelwert/Durchschnitt der Stichproben (Schätzung des Populationsmittelwerts)
*/
mean: number;
/**
* Varianz der Stichproben (Schätzung der Populationsvarianz)
*/
variance: number;
/**
* Standardabweichung der Stichproben (Schätzung der Populationsstandardabweichung)
*/
sd: number;
/**
* Standardfehler des Mittelwerts (bekannt als die Standardabweichung der Stichprobenverteilung des Stichprobenmittelwerts)
*/
sem: number;
/**
* Freiheitsgrade
*/
df: number;
/**
* kritischer Wert der Stichproben
*/
critical: number;
/**
* Fehlerbereich
*/
moe: number;
/**
* relativer Fehlerbereich
*/
rme: number;
/**
* Median der absoluten Abweichung
*/
mad: number;
/**
* p50/Median-Perzentil
*/
p50: number;
/**
* p75-Perzentil
*/
p75: number;
/**
* p99-Perzentil
*/
p99: number;
/**
* p995-Perzentil
*/
p995: number;
/**
* p999-Perzentil
*/
p999: number;
}bench.skip
- Typ:
(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void
Sie können die Syntax bench.skip verwenden, um die Ausführung bestimmter Benchmarks zu überspringen.
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
Verwenden Sie bench.only, um nur bestimmte Benchmarks in einer Benchmark-Suite auszuführen. Dies ist beim Debuggen nützlich.
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
Verwenden Sie bench.todo, um Benchmarks zu kennzeichnen, die später implementiert werden sollen.
import { bench } from 'vitest';
bench.todo('unimplemented test');describe
Wenn Sie test oder bench auf oberster Ebene einer Datei verwenden, werden diese als Teil der impliziten Suite erfasst. Mit describe können Sie im aktuellen Kontext eine neue Suite definieren, die aus zusammengehörigen Tests, Benchmarks oder weiteren, verschachtelten Suites besteht. Eine Suite ermöglicht es Ihnen, Ihre Tests und Benchmarks zu organisieren, wodurch die Berichte übersichtlicher werden.
// basic.spec.ts
// organizing tests
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
// organizing benchmarks
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;
});
});
});Sie können describe-Blöcke auch verschachteln, um eine Hierarchie von Tests oder Benchmarks zu erstellen:
import { describe, expect, test } from 'vitest';
function numberToCurrency(value: number | string) {
if (typeof value !== 'number') {
throw new TypeError('Value must be a number');
}
return value
.toFixed(2)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
describe('numberToCurrency', () => {
describe('given an invalid number', () => {
test('composed of non-numbers to throw error', () => {
expect(() => numberToCurrency('abc')).toThrowError();
});
});
describe('given a valid number', () => {
test('returns the correct currency format', () => {
expect(numberToCurrency(10000)).toBe('10,000.00');
});
});
});describe.skip
- Alias:
suite.skip
Verwenden Sie describe.skip innerhalb einer Suite, um die Ausführung eines bestimmten describe-Blocks zu verhindern.
import { assert, describe, test } from 'vitest';
describe.skip('skipped suite', () => {
test('sqrt', () => {
// Suite skipped, no error
assert.equal(Math.sqrt(4), 3);
});
});describe.skipIf
- Alias:
suite.skipIf
Es kann vorkommen, dass Sie Suites mehrfach mit unterschiedlichen Umgebungen ausführen, wobei einige der Suites umgebungsspezifisch sind. Anstatt die Suite mit einer if-Abfrage zu umschließen, können Sie describe.skipIf verwenden, um die Suite zu überspringen, wenn die Bedingung erfüllt ist.
import { describe, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
describe.skipIf(isDev)('prod only test', () => {
// this test only runs in production
});WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest zur Typüberprüfung einsetzen.
describe.runIf
- Alias:
suite.runIf
Das Gegenteil von describe.skipIf.
import { assert, describe, test } from 'vitest';
const isDev = process.env.NODE_ENV === 'development';
describe.runIf(isDev)('dev only test suite', () => {
// this test suite only runs in development
});WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest als Typüberprüfer verwenden.
describe.only
- Typ:
(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void
Verwenden Sie describe.only, um nur bestimmte Suites auszuführen.
import { assert, describe, test } from 'vitest';
// Only this suite (and others marked with only) are run
describe.only('suite', () => {
test('sqrt', () => {
assert.equal(Math.sqrt(4), 3);
});
});
describe('other suite', () => {
// ... will be skipped
});Es kann nützlich sein, only-Tests in einer bestimmten Datei auszuführen und dabei alle anderen Tests der gesamten Testsuite zu ignorieren, die die Ausgabe beeinträchtigen könnten.
Führen Sie dazu vitest mit der spezifischen Datei aus, die die entsprechenden Tests enthält.
# vitest interesting.test.tsdescribe.concurrent
- Alias:
suite.concurrent
describe.concurrent führt alle inneren Suiten und Tests parallel aus
import { describe, test } from 'vitest';
// Alle Suiten und Tests innerhalb dieser Suite werden parallel ausgeführt
describe.concurrent('suite', () => {
test('concurrent test 1', async () => {
/* ... */
});
describe('concurrent suite 2', async () => {
test('concurrent test inner 1', async () => {
/* ... */
});
test('concurrent test inner 2', async () => {
/* ... */
});
});
test.concurrent('concurrent test 3', async () => {
/* ... */
});
});.skip, .only und .todo funktionieren mit Concurrent-Suites. Alle folgenden Kombinationen sind gültig:
describe.concurrent(/* ... */);
describe.skip.concurrent(/* ... */); // or describe.concurrent.skip(/* ... */)
describe.only.concurrent(/* ... */); // or describe.concurrent.only(/* ... */)
describe.todo.concurrent(/* ... */); // or describe.concurrent.todo(/* ... */)Bei der Ausführung von Concurrent-Tests müssen Snapshots und Assertions expect aus dem lokalen Testkontext verwenden, um sicherzustellen, dass der korrekte Test erkannt wird.
describe.concurrent('suite', () => {
test('concurrent test 1', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
test('concurrent test 2', async ({ expect }) => {
expect(foo).toMatchSnapshot();
});
});WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest zur Typüberprüfung einsetzen.
describe.sequential
- Alias:
suite.sequential
describe.sequential innerhalb einer Suite markiert jeden Test als "sequential" (sequenziell/nacheinander ablaufend). Dies ist nützlich, wenn Sie Tests sequenziell innerhalb von describe.concurrent oder mit der Befehlszeilenoption --sequence.concurrent ausführen möchten.
import { describe, test } from 'vitest';
describe.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
- Alias:
suite.shuffle
Vitest bietet die Möglichkeit, alle Tests in zufälliger Reihenfolge über das CLI-Flag --sequence.shuffle oder die Konfigurationsoption sequence.shuffle auszuführen. Wenn Sie jedoch nur einen Teil Ihrer Testsuite in zufälliger Reihenfolge ausführen möchten, können Sie diesen mit diesem Flag markieren.
import { describe, test } from 'vitest';
describe.shuffle('suite', () => {
test('random test 1', async () => {
/* ... */
});
test('random test 2', async () => {
/* ... */
});
test('random test 3', async () => {
/* ... */
});
});
// order depends on sequence.seed option in config (Date.now() by default).skip, .only und .todo funktionieren mit zufälligen Suites.
WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest zur Typüberprüfung einsetzen.
describe.todo
- Alias:
suite.todo
Verwenden Sie describe.todo, um Suites als Platzhalter zu definieren, die später implementiert werden sollen. Ein Eintrag wird im Bericht für die Tests angezeigt, sodass Sie wissen, wie viele Tests Sie noch implementieren müssen.
// An entry will be shown in the report for this suite
describe.todo('unimplemented suite');describe.each
- Alias:
suite.each
Verwenden Sie describe.each, wenn Sie mehrere Tests haben, die von denselben Daten abhängen.
import { describe, expect, test } from 'vitest';
describe.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);
});
});Ab Vitest 0.25.3 können Sie auch eine Template-String-Tabelle verwenden.
- Die erste Zeile sollte die Spaltennamen enthalten, getrennt durch
|; - Eine oder mehrere nachfolgende Datenzeilen, die als Template-Literal-Ausdrücke mit der Syntax
${value}bereitgestellt werden.
import { describe, expect, test } from 'vitest';
describe.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);
});
});WARNING
Sie können diese Syntax nicht verwenden, wenn Sie Vitest zur Typüberprüfung einsetzen.
Setup und Teardown
Diese Funktionen ermöglichen es Ihnen, in den Lebenszyklus von Tests einzugreifen, um sich wiederholenden Setup- und Teardown-Code zu vermeiden. Sie gelten für den aktuellen Kontext: die Datei, wenn sie auf oberster Ebene verwendet werden, oder die aktuelle Suite, wenn sie sich innerhalb eines describe-Blocks befinden. Diese Hooks werden nicht aufgerufen, wenn Sie Vitest zur Typüberprüfung verwenden.
beforeEach
- Typ:
beforeEach(fn: () => Awaitable<void>, timeout?: number)
Registriert einen Callback, der vor jedem Test im aktuellen Kontext aufgerufen wird. Wenn die Funktion eine Promise zurückgibt, wartet Vitest, bis die Promise aufgelöst ist, bevor der Test ausgeführt wird.
Optional können Sie ein Timeout (in Millisekunden) übergeben, das definiert, wie lange gewartet werden soll, bevor der Vorgang abgebrochen wird. Der Standardwert ist 5 Sekunden.
import { beforeEach } from 'vitest';
beforeEach(async () => {
// Clear mocks and add some testing data after before each test run
await stopMocking();
await addUser({ name: 'John' });
});Hier stellt beforeEach sicher, dass vor jedem Test ein Benutzer hinzugefügt wird.
beforeEach auch eine optionale Bereinigungsfunktion (entspricht afterEach).
import { beforeEach } from 'vitest';
beforeEach(async () => {
// called once before each test run
await prepareSomething();
// clean up function, called once after each test run
return async () => {
await resetSomething();
};
});afterEach
- Typ:
afterEach(fn: () => Awaitable<void>, timeout?: number)
Registriert einen Callback, der aufgerufen wird, nachdem jeder Test im aktuellen Kontext abgeschlossen wurde. Wenn die Funktion eine Promise zurückgibt, wartet Vitest, bis die Promise aufgelöst ist, bevor fortgefahren wird.
Optional können Sie ein Timeout (in Millisekunden) angeben, um festzulegen, wie lange gewartet werden soll, bevor der Vorgang abgebrochen wird. Der Standardwert ist 5 Sekunden.
import { afterEach } from 'vitest';
afterEach(async () => {
await clearTestingData(); // clear testing data after each test run
});Hier stellt afterEach sicher, dass die Testdaten nach jedem Testlauf bereinigt werden.
TIP
Vitest 1.3.0 hat den onTestFinished Hook hinzugefügt. Sie können ihn während der Testausführung aufrufen, um jeglichen Zustand zu bereinigen, nachdem der Test abgeschlossen wurde.
beforeAll
- Typ:
beforeAll(fn: () => Awaitable<void>, timeout?: number)
Registriert einen Callback, der einmal aufgerufen wird, bevor mit der Ausführung aller Tests im aktuellen Kontext begonnen wird. Wenn die Funktion eine Promise zurückgibt, wartet Vitest, bis die Promise aufgelöst ist, bevor Tests ausgeführt werden.
Optional können Sie ein Timeout (in Millisekunden) angeben, um festzulegen, wie lange gewartet werden soll, bevor der Vorgang abgebrochen wird. Der Standardwert ist 5 Sekunden.
import { beforeAll } from 'vitest';
beforeAll(async () => {
await startMocking(); // called once before all tests run
});Hier stellt beforeAll sicher, dass die Mock-Daten vor der Ausführung der Tests eingerichtet werden.
beforeAll auch eine optionale Bereinigungsfunktion (entspricht afterAll).
import { beforeAll } from 'vitest';
beforeAll(async () => {
// called once before all tests run
await startMocking();
// clean up function, called once after all tests run
return async () => {
await stopMocking();
};
});afterAll
- Typ:
afterAll(fn: () => Awaitable<void>, timeout?: number)
Registriert einen Callback, der einmal aufgerufen wird, nachdem alle Tests im aktuellen Kontext ausgeführt wurden. Wenn die Funktion eine Promise zurückgibt, wartet Vitest, bis die Promise aufgelöst ist, bevor fortgefahren wird.
Optional können Sie ein Timeout (in Millisekunden) angeben, um festzulegen, wie lange gewartet werden soll, bevor der Vorgang abgebrochen wird. Der Standardwert ist 5 Sekunden.
import { afterAll } from 'vitest';
afterAll(async () => {
await stopMocking(); // this method is called after all tests run
});Hier stellt afterAll sicher, dass die Methode stopMocking aufgerufen wird, nachdem alle Tests ausgeführt wurden.
Testhaken
Vitest stellt einige Hooks bereit, die Sie während der Testausführung aufrufen können, um den Zustand zu bereinigen, nachdem der Test abgeschlossen ist.
WARNING
Diese Hooks lösen einen Fehler aus, wenn sie außerhalb des Testkörpers aufgerufen werden.
onTestFinished
Dieser Hook wird immer aufgerufen, nachdem der Test abgeschlossen wurde. Er wird nach den afterEach-Hooks aufgerufen, da diese das Testergebnis beeinflussen können. Er empfängt ein TaskResult-Objekt mit dem aktuellen Testergebnis.
import { onTestFinished, test } from 'vitest';
test('führt eine Abfrage aus', () => {
const db = connectDb();
onTestFinished(() => db.close());
db.query('SELECT * FROM users');
});WARNING
Wenn Sie Tests gleichzeitig ausführen, sollten Sie immer den onTestFinished-Hook aus dem Testkontext verwenden, da Vitest gleichzeitige Tests nicht in globalen Hooks verfolgt:
import { test from 'vitest'
test.concurrent('führt eine Abfrage aus', ({ onTestFinished }) => {
const db = connectDb()
onTestFinished(() => db.close())
db.query('SELECT * FROM users')
})Dieser Hook ist besonders nützlich, wenn Sie wiederverwendbare Logik erstellen:
// dies kann in einer separaten Datei stehen
function getTestDb() {
const db = connectMockedDb();
onTestFinished(() => db.close());
return db;
}
test('führt eine Benutzerabfrage aus', async () => {
const db = getTestDb();
expect(await db.query('SELECT * from users').perform()).toEqual([]);
});
test('führt eine Organisationsabfrage aus', async () => {
const db = getTestDb();
expect(await db.query('SELECT * from organizations').perform()).toEqual([]);
});TIP
Dieser Hook wird immer in umgekehrter Reihenfolge aufgerufen und wird nicht von der Option sequence.hooks beeinflusst.
onTestFailed
Dieser Hook wird nur aufgerufen, nachdem der Test fehlgeschlagen ist. Er wird nach den afterEach-Hooks aufgerufen, da diese das Testergebnis beeinflussen können. Er empfängt ein TaskResult-Objekt mit dem aktuellen Testergebnis. Dieser Hook ist nützlich für die Fehlersuche.
import { onTestFailed, test } from 'vitest';
test('führt eine Abfrage aus', () => {
const db = connectDb();
onTestFailed(e => {
console.log(e.result.errors);
});
db.query('SELECT * FROM users');
});WARNING
Wenn Sie Tests gleichzeitig ausführen, sollten Sie immer den onTestFailed-Hook aus dem Testkontext verwenden, da Vitest gleichzeitige Tests nicht in globalen Hooks verfolgt:
import { test from 'vitest'
test.concurrent('führt eine Abfrage aus', ({ onTestFailed }) => {
const db = connectDb()
onTestFailed((result) => {
console.log(result.errors)
})
db.query('SELECT * FROM users')
})