Extensión de Reporteros
Puedes importar reporteros desde vitest/reporters
y extenderlos para crear tus propios reporteros personalizados.
Extensión de Reporteros Integrados
En general, no necesitas crear tu reportero desde cero. vitest
incluye varios reporteros predeterminados que puedes extender.
import { DefaultReporter } from 'vitest/reporters';
export default class MyDefaultReporter extends DefaultReporter {
// realizar alguna acción
}
Por supuesto, también puedes crear tu reportero desde cero. Simplemente extiende la clase BaseReporter
e implementa los métodos que necesites.
A continuación, se muestra un ejemplo de un reportero personalizado:
// ./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);
}
}
O implementa la interfaz Reporter
:
// ./custom-reporter.js
import { Reporter } from 'vitest/reporters';
export default class CustomReporter implements Reporter {
onCollected() {
// imprimir algún mensaje
}
}
Luego puedes usar tu reportero personalizado en el archivo vitest.config.ts
:
import { defineConfig } from 'vitest/config';
import CustomReporter from './custom-reporter.js';
export default defineConfig({
test: {
reporters: [new CustomReporter()],
},
});
Tareas Reportadas
WARNING
Esta es una API experimental. Los cambios significativos podrían no seguir SemVer. Por favor, fija la versión de Vitest cuando la uses.
Puedes acceder a esta API llamando a vitest.state.getReportedEntity(runnerTask)
:
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) {
// ten presente que la implementación de tareas anterior usa "file" en lugar de "module"
const testModule = this.ctx.state.getReportedEntity(
fileTask
) as TestModule;
for (const task of testModule.children) {
// ^?
console.log('finished', task.type, task.fullName);
}
}
}
}
Estamos planeando estabilizar esta API en Vitest 2.1.
TestCase
TestCase
representa una única prueba.
declare class TestCase {
readonly type = 'test' | 'custom';
/**
* Instancia de tarea.
* @experimental La API pública de tareas es experimental y no sigue SemVer.
*/
readonly task: RunnerTestCase | RunnerCustomCase;
/**
* El proyecto asociado a la prueba.
*/
readonly project: TestProject;
/**
* Referencia directa al módulo de prueba donde se define la prueba.
*/
readonly module: TestModule;
/**
* Nombre de la prueba.
*/
readonly name: string;
/**
* Nombre completo de la prueba, incluyendo todas las suites padre separadas por `>`.
*/
readonly fullName: string;
/**
* Identificador único.
* Este ID es determinista y será el mismo para la misma prueba en múltiples ejecuciones.
* El ID se basa en el nombre del proyecto, el ID del módulo y la posición de la prueba.
*/
readonly id: string;
/**
* Ubicación en el módulo donde se definió la prueba.
* Las ubicaciones se recolectan solo si `includeTaskLocation` está habilitado en la configuración.
*/
readonly location: { line: number; column: number } | undefined;
/**
* Suite padre. Si la prueba se llamó directamente dentro del módulo, el padre será el propio módulo.
*/
readonly parent: TestSuite | TestModule;
/**
* Opciones con las que se inició la prueba.
*/
readonly options: TaskOptions;
/**
* Comprueba si la prueba no hizo que la suite fallara.
* Si la prueba aún no ha terminado o fue saltada, devolverá `true`.
*/
ok(): boolean;
/**
* Metadatos personalizados que se adjuntaron a la prueba durante su ejecución.
*/
meta(): TaskMeta;
/**
* Resultados de la prueba. Será `undefined` si la prueba aún no ha terminado o simplemente fue recolectada.
*/
result(): TestResult | undefined;
/**
* Información útil sobre la prueba, como duración, uso de memoria, etc.
*/
diagnostic(): TestDiagnostic | undefined;
}
export type TestResult =
| TestResultPassed
| TestResultFailed
| TestResultSkipped;
export interface TestResultPassed {
/**
* La prueba se ejecutó con éxito.
*/
state: 'passed';
/**
* Errores que se lanzaron durante la ejecución de la prueba.
*
* **Nota**: Si la prueba se reintentó con éxito, los errores aún se reportarán.
*/
errors: TestError[] | undefined;
}
export interface TestResultFailed {
/**
* La prueba no se ejecutó correctamente.
*/
state: 'failed';
/**
* Errores que se lanzaron durante la ejecución de la prueba.
*/
errors: TestError[];
}
export interface TestResultSkipped {
/**
* La prueba fue saltada con el flag `only`, `skip` o `todo`.
* Puedes ver cuál se usó en la opción `mode`.
*/
state: 'skipped';
/**
* Las pruebas saltadas no tienen errores.
*/
errors: undefined;
}
export interface TestDiagnostic {
/**
* Si la duración de la prueba supera `slowTestThreshold`.
*/
slow: boolean;
/**
* La cantidad de memoria consumida por la prueba en bytes.
* Este valor solo está disponible si la prueba se ejecutó con el flag `logHeapUsage`.
*/
heap: number | undefined;
/**
* El tiempo que tarda en ejecutarse la prueba en ms.
*/
duration: number;
/**
* El tiempo en ms en que comenzó la prueba.
*/
startTime: number;
/**
* El número de reintentos de la prueba.
*/
retryCount: number;
/**
* El número de repeticiones de la prueba según la configuración de la opción `repeats`.
* Este valor puede ser menor si la prueba falló durante la repetición y no se configuró `retry`.
*/
repeatCount: number;
/**
* Si la prueba pasó en un segundo reintento.
*/
flaky: boolean;
}
TestSuite
TestSuite
representa una única suite que contiene pruebas y otras suites.
declare class TestSuite {
readonly type = 'suite';
/**
* Instancia de tarea.
* @experimental La API pública de tareas es experimental y no sigue SemVer.
*/
readonly task: RunnerTestSuite;
/**
* El proyecto asociado a la prueba.
*/
readonly project: TestProject;
/**
* Referencia directa al módulo de prueba donde se define la suite.
*/
readonly module: TestModule;
/**
* Nombre de la suite.
*/
readonly name: string;
/**
* Nombre completo de la suite, incluyendo todas las suites padre separadas por `>`.
*/
readonly fullName: string;
/**
* Identificador único.
* Este ID es determinista y será el mismo para la misma prueba en múltiples ejecuciones.
* El ID se basa en el nombre del proyecto, el ID del módulo y la posición de la prueba.
*/
readonly id: string;
/**
* Ubicación en el módulo donde se definió la suite.
* Las ubicaciones se recolectan solo si `includeTaskLocation` está habilitado en la configuración.
*/
readonly location: { line: number; column: number } | undefined;
/**
* Colección de suites y pruebas que forman parte de esta suite.
*/
readonly children: TaskCollection;
/**
* Opciones con las que se inició la suite.
*/
readonly options: TaskOptions;
}
TestModule
TestModule
representa un único archivo que contiene suites y pruebas.
declare class TestModule extends SuiteImplementation {
readonly type = 'module';
/**
* Instancia de tarea.
* @experimental La API pública de tareas es experimental y no sigue SemVer.
*/
readonly task: RunnerTestFile;
/**
* Colección de suites y pruebas que forman parte de este módulo.
*/
readonly children: TestCollection;
/**
* Normalmente es una ruta de archivo Unix absoluta.
* Puede ser un ID virtual si el archivo no está en el disco.
* Este valor corresponde al ID de `ModuleGraph` de Vite.
*/
readonly moduleId: string;
/**
* Información útil sobre el módulo, como duración, uso de memoria, etc.
* Si el módulo aún no se ha ejecutado, todos los valores de diagnóstico devolverán `0`.
*/
diagnostic(): ModuleDiagnostic;
}
export interface ModuleDiagnostic {
/**
* El tiempo que toma importar e iniciar un entorno.
*/
environmentSetupDuration: number;
/**
* El tiempo que tarda Vitest en configurar la infraestructura de pruebas (runner, mocks, etc.).
*/
prepareDuration: number;
/**
* El tiempo que tarda en importar el módulo de prueba.
* Esto incluye importar todo en el módulo y ejecutar los callbacks de la suite.
*/
collectDuration: number;
/**
* El tiempo que tarda en importar el módulo de configuración.
*/
setupDuration: number;
/**
* Duración acumulada de todas las pruebas y hooks en el módulo.
*/
duration: number;
}
TestCollection
TestCollection
representa una colección de suites y pruebas. También proporciona métodos útiles para iterar sobre sí misma.
declare class TestCollection {
/**
* Devuelve la prueba o suite en un índice específico del array.
*/
at(index: number): TestCase | TestSuite | undefined;
/**
* El número de pruebas y suites en la colección.
*/
size: number;
/**
* Devuelve la colección en forma de array para una manipulación más sencilla.
*/
array(): (TestCase | TestSuite)[];
/**
* Filtra todas las suites que forman parte de esta colección y sus hijos.
*/
allSuites(): IterableIterator<TestSuite>;
/**
* Filtra todas las pruebas que forman parte de esta colección y sus hijos.
*/
allTests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>;
/**
* Filtra solo las pruebas que forman parte de esta colección.
*/
tests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>;
/**
* Filtra solo las suites que forman parte de esta colección.
*/
suites(): IterableIterator<TestSuite>;
[Symbol.iterator](): IterableIterator<TestSuite | TestCase>;
}
Por ejemplo, puedes iterar sobre todas las pruebas dentro de un módulo llamando a testModule.children.allTests()
:
function onFileCollected(testModule: TestModule): void {
console.log('collecting tests in', testModule.moduleId);
// Itera sobre todas las pruebas y suites en el módulo
for (const task of testModule.children.allTests()) {
console.log('collected', task.type, task.fullName);
}
}
TestProject
TestProject
es un proyecto asociado al módulo. Cada prueba y suite dentro de ese módulo hará referencia al mismo proyecto.
El proyecto es útil para obtener la configuración o el contexto proporcionado.
declare class TestProject {
/**
* La instancia global de Vitest.
* @experimental La API pública de Vitest es experimental y no sigue SemVer.
*/
readonly vitest: Vitest;
/**
* El proyecto del área de trabajo al que está asociado este proyecto de prueba.
* @experimental La API pública de Vitest es experimental y no sigue SemVer.
*/
readonly workspaceProject: WorkspaceProject;
/**
* Instancia del servidor de desarrollo de Vite. Cada proyecto de área de trabajo tiene su propio servidor.
*/
readonly vite: ViteDevServer;
/**
* Configuración del proyecto resuelta.
*/
readonly config: ResolvedProjectConfig;
/**
* Configuración global resuelta. Si no hay proyectos de área de trabajo, será la misma que `config`.
*/
readonly globalConfig: ResolvedConfig;
/**
* Configuración del proyecto serializada. Esta es la configuración que reciben las pruebas.
*/
get serializedConfig(): SerializedConfig;
/**
* El nombre del proyecto o una cadena vacía si no está configurado.
*/
name(): string;
/**
* Contexto personalizado que se provee al proyecto.
*/
context(): ProvidedContext;
/**
* Provee un contexto serializable personalizado al proyecto. Este contexto estará disponible para las pruebas una vez que se ejecuten.
*/
provide<T extends keyof ProvidedContext & string>(
key: T,
value: ProvidedContext[T]
): void;
}
Reporteros Exportados
vitest
incluye algunos reporteros integrados que puedes usar directamente.
Reporteros integrados:
BasicReporter
DefaultReporter
DotReporter
JsonReporter
VerboseReporter
TapReporter
JUnitReporter
TapFlatReporter
HangingProcessReporter
Clases base abstractas de reporteros:
BaseReporter
Interfaces de reporteros:
Reporter