Testkontext
Inspiriert von Playwright Fixtures ermöglicht der Testkontext von Vitest das Definieren von Hilfsfunktionen, Zuständen und Fixtures, die in Ihren Tests verwendet werden können.
Verwendung
Das erste Argument jedes Test-Callbacks ist ein Testkontext.
import { it } from 'vitest';
it('sollte funktionieren', ctx => {
// gibt den Namen der Testaufgabe aus
console.log(ctx.task.name);
});
Eingebauter Testkontext
context.task
Ein Nur-Lese-Objekt, das Metadaten über den aktuellen Test enthält.
context.expect
Die expect
-API, die mit dem aktuellen Test verbunden ist:
import { it } from 'vitest';
it('Mathe ist einfach', ({ expect }) => {
expect(2 + 2).toBe(4);
});
Diese API ist nützlich, um Snapshot-Tests parallel auszuführen, da die globale expect
-Funktion dies nicht verfolgen kann:
import { it } from 'vitest';
it.concurrent('Mathe ist einfach', ({ expect }) => {
expect(2 + 2).toMatchInlineSnapshot();
});
it.concurrent('Mathe ist schwer', ({ expect }) => {
expect(2 * 2).toMatchInlineSnapshot();
});
context.skip
Überspringt die Ausführung des aktuellen Tests und markiert ihn als übersprungen:
import { expect, it } from 'vitest';
it('Mathe ist schwer', ({ skip }) => {
skip();
expect(2 + 2).toBe(5);
});
Den Testkontext erweitern
Vitest bietet zwei verschiedene Möglichkeiten, um den Testkontext zu erweitern.
test.extend
WARNING
Diese API ist ab Vitest 0.32.3 verfügbar.
Wie Playwright können Sie diese Methode verwenden, um Ihre eigene test
-API mit benutzerdefinierten Fixtures zu definieren und diese wiederzuverwenden.
Beispielsweise erstellen wir zuerst myTest
mit den zwei Fixtures todos
und archive
.
// my-test.ts
import { test } from 'vitest';
const todos = [];
const archive = [];
export const myTest = test.extend({
todos: async ({ task }, use) => {
// Richten Sie die Fixture vor jeder Testausführung ein
todos.push(1, 2, 3);
// Verwenden Sie den Fixture-Wert
await use(todos);
// Fixture bereinigen
todos.length = 0;
},
archive,
});
Dann können wir es importieren und verwenden.
import { expect } from 'vitest';
import { myTest } from './my-test.ts';
myTest('Elemente zu todos hinzufügen', ({ todos }) => {
expect(todos.length).toBe(3);
todos.push(4);
expect(todos.length).toBe(4);
});
myTest('Elemente von todos zu Archiv verschieben', ({ todos, archive }) => {
expect(todos.length).toBe(3);
expect(archive.length).toBe(0);
archive.push(todos.pop()!);
expect(todos.length).toBe(2);
expect(archive.length).toBe(1);
});
Wir können auch zusätzliche Fixtures hinzufügen oder bestehende überschreiben, indem wir myTest
erweitern.
export const myTest2 = myTest.extend({
settings: {
// ...
},
});
Fixture-Initialisierung
Der Vitest-Runner initialisiert Ihre Fixtures intelligent und injiziert sie basierend auf der Verwendung in den Testkontext.
import { test } from 'vitest';
async function todosFn({ task }, use) {
await use([1, 2, 3]);
}
const myTest = test.extend({
todos: todosFn,
archive: [],
});
// todosFn wird nicht aufgerufen
myTest('', () => {});
myTest('', ({ archive }) => {});
// todosFn wird ausgeführt
myTest('', ({ todos }) => {});
WARNING
Wenn Sie test.extend()
zusammen mit Fixtures verwenden, sollten Sie immer das Muster der Objekt-Destrukturierung { todos }
verwenden, um sowohl in der Fixture-Funktion als auch in der Testfunktion auf den Kontext zuzugreifen.
TypeScript
Um Typen für alle benutzerdefinierten Kontexte bereitzustellen, können Sie den Fixture-Typ als Generic übergeben.
interface MyFixtures {
todos: number[];
archive: number[];
}
const myTest = test.extend<MyFixtures>({
todos: [],
archive: [],
});
myTest('', context => {
expectTypeOf(context.todos).toEqualTypeOf<number[]>();
expectTypeOf(context.archive).toEqualTypeOf<number[]>();
});
beforeEach
und afterEach
Die Kontexte sind für jeden Test unterschiedlich. Sie können innerhalb der beforeEach
- und afterEach
-Hooks auf sie zugreifen und sie erweitern.
import { beforeEach, it } from 'vitest';
beforeEach(async context => {
// den Kontext erweitern
context.foo = 'bar';
});
it('sollte funktionieren', ({ foo }) => {
console.log(foo); // 'bar'
});
TypeScript
Um Typen für alle benutzerdefinierten Kontexte bereitzustellen, können Sie den Typ TestContext
erweitern, indem Sie Folgendes hinzufügen:
declare module 'vitest' {
export interface TestContext {
foo?: string;
}
}
Wenn Sie Eigenschaftstypen nur für bestimmte beforeEach
-, afterEach
-, it
- und test
-Hooks bereitstellen möchten, können Sie den Typ als Generic übergeben.
interface LocalTestContext {
foo: string;
}
beforeEach<LocalTestContext>(async context => {
// typeof context is 'TestContext & LocalTestContext'
context.foo = 'bar';
});
it<LocalTestContext>('sollte funktionieren', ({ foo }) => {
// typeof foo is 'string'
console.log(foo); // 'bar'
});