Reporter erweitern
Sie können Reporter aus vitest/reporters
importieren und erweitern, um Ihre eigenen benutzerdefinierten Reporter zu erstellen.
Integrierte Reporter erweitern
Im Allgemeinen müssen Sie Ihren Reporter nicht von Grund auf neu erstellen. vitest
wird mit mehreren Standard-Reportern geliefert, die Sie erweitern können.
import { DefaultReporter } from 'vitest/reporters';
export default class MyDefaultReporter extends DefaultReporter {
// irgendetwas tun
}
Alternativ können Sie Ihren Reporter von Grund auf neu erstellen. Erweitern Sie einfach die Klasse BaseReporter
und implementieren Sie die benötigten Methoden.
Hier ist ein Beispiel für einen benutzerdefinierten Reporter:
// ./custom-reporter.js
import { BaseReporter } from 'vitest/reporters';
export default class CustomReporter extends BaseReporter {
onCollected() {
const files = this.ctx.state.getFiles(this.watchFilters);
this.reportTestSummary(files);
}
}
Oder implementieren Sie das Reporter
-Interface:
// ./custom-reporter.js
import { Reporter } from 'vitest/reporters';
export default class CustomReporter implements Reporter {
onCollected() {
// etwas ausgeben
}
}
Sie können Ihren benutzerdefinierten Reporter in der Datei vitest.config.ts
verwenden:
import { defineConfig } from 'vitest/config';
import CustomReporter from './custom-reporter.js';
export default defineConfig({
test: {
reporters: [new CustomReporter()],
},
});
Berichtete Aufgaben
WARNING
Dies ist eine experimentelle API. Abwärtsinkompatible Änderungen folgen möglicherweise nicht SemVer. Bitte fixieren Sie die Vitest-Version, wenn Sie sie verwenden.
Sie können auf diese API zugreifen, indem Sie vitest.state.getReportedEntity(runnerTask)
aufrufen:
import type { Vitest } from 'vitest/node';
import type { RunnerTestFile } from 'vitest';
import type { Reporter, TestModule } from 'vitest/reporters';
class MyReporter implements Reporter {
ctx!: Vitest;
onInit(ctx: Vitest) {
this.ctx = ctx;
}
onFinished(files: RunnerTestFile[]) {
for (const fileTask of files) {
// Beachten Sie, dass die alte Aufgabenimplementierung "file" anstelle von "module" verwendet wird.
const testModule = this.ctx.state.getReportedEntity(
fileTask
) as TestModule;
for (const task of testModule.children) {
// ^?
console.log('finished', task.type, task.fullName);
}
}
}
}
Wir planen, diese API in Vitest 2.1 zu stabilisieren.
TestCase
TestCase
stellt einen einzelnen Test dar.
declare class TestCase {
readonly type = 'test' | 'custom';
/**
* Aufgabeninstanz.
* @experimental Die öffentliche Aufgaben-API ist experimentell und folgt nicht semver.
*/
readonly task: RunnerTestCase | RunnerCustomCase;
/**
* Das Projekt, das dem Test zugeordnet ist.
*/
readonly project: TestProject;
/**
* Direkter Verweis auf das Testmodul, in dem der Test definiert ist.
*/
readonly module: TestModule;
/**
* Name des Tests.
*/
readonly name: string;
/**
* Vollständiger Name des Tests, einschließlich aller übergeordneten Suiten, getrennt durch `>`.
*/
readonly fullName: string;
/**
* Eindeutige Kennung.
* Diese ID ist deterministisch und bleibt für denselben Test über mehrere Läufe hinweg gleich.
* Die ID basiert auf dem Projektnamen, der Modul-ID und der Testposition.
*/
readonly id: string;
/**
* Speicherort im Modul, an dem der Test definiert wurde.
* Speicherorte werden nur gesammelt, wenn `includeTaskLocation` in der Konfiguration aktiviert ist.
*/
readonly location: { line: number; column: number } | undefined;
/**
* Übergeordnete Suite. Wenn der Test direkt innerhalb des Moduls aufgerufen wurde, ist das übergeordnete Element das Modul selbst.
*/
readonly parent: TestSuite | TestModule;
/**
* Optionen, mit denen der Test initialisiert wurde.
*/
readonly options: TaskOptions;
/**
* Überprüft, ob der Test nicht zum Fehlschlagen der Suite geführt hat.
* Wenn der Test noch nicht abgeschlossen oder übersprungen wurde, wird `true` zurückgegeben.
*/
ok(): boolean;
/**
* Benutzerdefinierte Metadaten, die während der Ausführung an den Test angehängt wurden.
*/
meta(): TaskMeta;
/**
* Testergebnisse. Ist `undefined`, wenn der Test noch nicht abgeschlossen oder gerade gesammelt wurde.
*/
result(): TestResult | undefined;
/**
* Nützliche Informationen über den Test wie Dauer, Speichernutzung usw.
*/
diagnostic(): TestDiagnostic | undefined;
}
export type TestResult =
| TestResultPassed
| TestResultFailed
| TestResultSkipped;
export interface TestResultPassed {
/**
* Der Test wurde erfolgreich bestanden.
*/
state: 'passed';
/**
* Fehler, die während der Testausführung aufgetreten sind.
*
* **Hinweis**: Wenn der Test erfolgreich wiederholt wurde, werden Fehler weiterhin gemeldet.
*/
errors: TestError[] | undefined;
}
export interface TestResultFailed {
/**
* Der Test konnte nicht ausgeführt werden.
*/
state: 'failed';
/**
* Fehler, die während der Testausführung aufgetreten sind.
*/
errors: TestError[];
}
export interface TestResultSkipped {
/**
* Der Test wurde mit dem Flag `only`, `skip` oder `todo` übersprungen.
* Sie können in der Option `mode` sehen, welches verwendet wurde.
*/
state: 'skipped';
/**
* Übersprungene Tests haben keine Fehler.
*/
errors: undefined;
}
export interface TestDiagnostic {
/**
* Wenn die Dauer des Tests über dem Schwellenwert für langsame Tests liegt.
*/
slow: boolean;
/**
* Die Menge des vom Test verwendeten Speichers in Bytes.
* Dieser Wert ist nur verfügbar, wenn der Test mit dem `logHeapUsage`-Flag ausgeführt wurde.
*/
heap: number | undefined;
/**
* Die Zeit, die zur Ausführung des Tests benötigt wird, in ms.
*/
duration: number;
/**
* Die Zeit in ms, zu der der Test gestartet wurde.
*/
startTime: number;
/**
* Die Anzahl der Wiederholungen des Tests.
*/
retryCount: number;
/**
* Die Anzahl der Testläufe, wie in der Option `repeats` konfiguriert.
* Dieser Wert kann niedriger sein, wenn der Test während der Wiederholung fehlschlug und keine Wiederholungskonfiguration vorhanden ist.
*/
repeatCount: number;
/**
* Ob der Test flaky ist.
*/
flaky: boolean;
}
TestSuite
TestSuite
stellt eine einzelne Suite dar, die Tests und andere Suiten enthält.
declare class TestSuite {
readonly type = 'suite';
/**
* Aufgabeninstanz.
* @experimental Die öffentliche Aufgaben-API ist experimentell und folgt nicht semver.
*/
readonly task: RunnerTestSuite;
/**
* Das Projekt, das dem Test zugeordnet ist.
*/
readonly project: TestProject;
/**
* Direkter Verweis auf das Testmodul, in dem die Suite definiert ist.
*/
readonly module: TestModule;
/**
* Name der Suite.
*/
readonly name: string;
/**
* Vollständiger Name der Suite, einschließlich aller übergeordneten Suiten, getrennt durch `>`.
*/
readonly fullName: string;
/**
* Eindeutige Kennung.
* Diese ID ist deterministisch und bleibt für denselben Test über mehrere Läufe hinweg gleich.
* Die ID basiert auf dem Projektnamen, der Modul-ID und der Testposition.
*/
readonly id: string;
/**
* Speicherort im Modul, an dem die Suite definiert wurde.
* Speicherorte werden nur gesammelt, wenn `includeTaskLocation` in der Konfiguration aktiviert ist.
*/
readonly location: { line: number; column: number } | undefined;
/**
* Sammlung von Suiten und Tests, die Teil dieser Suite sind.
*/
readonly children: TaskCollection;
/**
* Optionen, mit denen die Suite initialisiert wurde.
*/
readonly options: TaskOptions;
}
TestModule
TestModule
stellt eine einzelne Datei dar, die Suiten und Tests enthält.
declare class TestModule extends SuiteImplementation {
readonly type = 'module';
/**
* Aufgabeninstanz.
* @experimental Die öffentliche Aufgaben-API ist experimentell und folgt nicht semver.
*/
readonly task: RunnerTestFile;
/**
* Sammlung von Suiten und Tests, die Teil dieses Moduls sind.
*/
readonly children: TestCollection;
/**
* Dies ist normalerweise ein absoluter Unix-Dateipfad.
* Es kann eine virtuelle ID sein, wenn die Datei nicht auf der Festplatte ist.
* Dieser Wert entspricht der `ModuleGraph`-ID von Vite.
*/
readonly moduleId: string;
/**
* Nützliche Informationen über das Modul wie Dauer, Speichernutzung usw.
* Wenn das Modul noch nicht ausgeführt wurde, geben alle Diagnosewerte `0` zurück.
*/
diagnostic(): ModuleDiagnostic;
}
export interface ModuleDiagnostic {
/**
* Die Zeit, die zum Importieren und Initialisieren einer Umgebung benötigt wird.
*/
environmentSetupDuration: number;
/**
* Die Zeit, die Vitest benötigt, um die Testumgebung (Runner, Mocks usw.) einzurichten.
*/
prepareDuration: number;
/**
* Die Zeit, die zum Importieren des Testmoduls benötigt wird.
* Dies beinhaltet das Importieren von allem im Modul und das Ausführen von Suite-Callbacks.
*/
collectDuration: number;
/**
* Die Zeit, die zum Importieren des Setup-Moduls benötigt wird.
*/
setupDuration: number;
/**
* Kumulierte Dauer aller Tests und Hooks im Modul.
*/
duration: number;
}
TestCollection
TestCollection
stellt eine Sammlung von Suiten und Tests dar. Sie bietet auch nützliche Methoden zur Iteration über sich selbst.
declare class TestCollection {
/**
* Gibt den Test oder die Suite an einem bestimmten Index im Array zurück.
*/
at(index: number): TestCase | TestSuite | undefined;
/**
* Die Anzahl der Tests und Suiten in der Sammlung.
*/
size: number;
/**
* Gibt die Sammlung in Array-Form zur einfacheren Manipulation zurück.
*/
array(): (TestCase | TestSuite)[];
/**
* Filtert alle Suiten, die Teil dieser Sammlung und ihrer Kinder sind.
*/
allSuites(): IterableIterator<TestSuite>;
/**
* Filtert alle Tests, die Teil dieser Sammlung und ihrer Kinder sind.
*/
allTests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>;
/**
* Filtert nur die Tests, die Teil dieser Sammlung sind.
*/
tests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>;
/**
* Filtert nur die Suiten, die Teil dieser Sammlung sind.
*/
suites(): IterableIterator<TestSuite>;
[Symbol.iterator](): IterableIterator<TestSuite | TestCase>;
}
Sie können beispielsweise über alle Tests innerhalb eines Moduls iterieren, indem Sie testModule.children.allTests()
aufrufen:
function onFileCollected(testModule: TestModule): void {
console.log('collecting tests in', testModule.moduleId);
// über alle Tests und Suiten im Modul iterieren
for (const task of testModule.children.allTests()) {
console.log('collected', task.type, task.fullName);
}
}
TestProject
TestProject
ist ein Projekt, das dem Modul zugeordnet ist. Jeder Test und jede Suite innerhalb dieses Moduls verweist auf dasselbe Projekt.
Das Projekt ist nützlich, um die Konfiguration oder den bereitgestellten Kontext abzurufen.
declare class TestProject {
/**
* Die globale Vitest-Instanz.
* @experimental Die öffentliche Vitest-API ist experimentell und folgt nicht semver.
*/
readonly vitest: Vitest;
/**
* Das Workspace-Projekt, dem dieses Testprojekt zugeordnet ist.
* @experimental Die öffentliche Vitest-API ist experimentell und folgt nicht semver.
*/
readonly workspaceProject: WorkspaceProject;
/**
* Die Dev-Server-Instanz von Vite. Jedes Workspace-Projekt hat seinen eigenen Server.
*/
readonly vite: ViteDevServer;
/**
* Aufgelöste Projektkonfiguration.
*/
readonly config: ResolvedProjectConfig;
/**
* Aufgelöste globale Konfiguration. Wenn keine Workspace-Projekte vorhanden sind, ist dies dasselbe wie `config`.
*/
readonly globalConfig: ResolvedConfig;
/**
* Serialisierte Projektkonfiguration. Dies ist die Konfiguration, die Tests erhalten.
*/
get serializedConfig(): SerializedConfig;
/**
* Der Name des Projekts oder ein leerer String, wenn nicht gesetzt.
*/
name(): string;
/**
* Benutzerdefinierter Kontext, der dem Projekt bereitgestellt wurde.
*/
context(): ProvidedContext;
/**
* Stellen Sie dem Projekt einen benutzerdefinierten serialisierbaren Kontext bereit. Dieser Kontext ist für Tests verfügbar, sobald sie ausgeführt werden.
*/
provide<T extends keyof ProvidedContext & string>(
key: T,
value: ProvidedContext[T]
): void;
}
Exportierte Reporter
vitest
wird mit einigen integrierten Reportern geliefert, die Sie sofort verwenden können.
Integrierte Reporter:
BasicReporter
DefaultReporter
DotReporter
JsonReporter
VerboseReporter
TapReporter
JUnitReporter
TapFlatReporter
HangingProcessReporter
Abstrakte Basisreporter:
BaseReporter
Interface-Reporter:
Reporter