Passer au contenu

Étendre les Rapporteurs

Vous pouvez importer des rapporteurs depuis vitest/reporters et les étendre pour créer vos rapporteurs personnalisés.

Étendre les Rapporteurs Intégrés

En général, vous n’avez pas besoin de créer votre rapporteur de zéro. vitest est livré avec plusieurs programmes de rapport par défaut que vous pouvez étendre.

import { DefaultReporter } from 'vitest/reporters'
export default class MyDefaultReporter extends DefaultReporter {
// faire quelque chose
}

Bien sûr, vous pouvez créer votre rapporteur de zéro. Il suffit d’étendre la classe BaseReporter et d’implémenter les méthodes dont vous avez besoin.

Et voici un exemple de rapporteur personnalisé :

./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)
}
}

Ou implémentez l’interface Reporter :

./custom-reporter.js
import { Reporter } from 'vitest/reporters'
export default class CustomReporter implements Reporter {
onCollected() {
// imprimer quelque chose
}
}

Ensuite, vous pouvez utiliser votre rapporteur personnalisé dans le fichier vitest.config.ts :

import { defineConfig } from 'vitest/config'
import CustomReporter from './custom-reporter.js'
export default defineConfig({
test: {
reporters: [new CustomReporter()],
},
})

Tâches Rapportées

TestCase

TestCase représente un test unique.

declare class TestCase {
readonly type = 'test' | 'custom'
/**
* Instance de tâche.
* @experimental L'API de tâche publique est expérimentale et ne suit pas semver.
*/
readonly task: RunnerTestCase | RunnerCustomCase
/**
* Le projet associé au test.
*/
readonly project: TestProject
/**
* Référence directe au fichier de test où le test est défini.
*/
readonly file: TestFile
/**
* Nom du test.
*/
readonly name: string
/**
* Nom complet du test incluant toutes les suites parentes séparées par `>`.
*/
readonly fullName: string
/**
* Identifiant unique.
* Cet ID est déterministe et sera le même pour le même test lors de plusieurs exécutions.
* L'ID est basé sur le nom du projet, le chemin du fichier et la position du test.
*/
readonly id: string
/**
* Emplacement dans le fichier où le test a été défini.
* Les emplacements ne sont collectés que si `includeTaskLocation` est activé dans la config.
*/
readonly location: { line: number; column: number } | undefined
/**
* Suite parente. Si le test a été appelé directement dans le fichier, la parente sera le fichier.
*/
readonly parent: TestSuite | TestFile
/**
* Options avec lesquelles le test a été initié.
*/
readonly options: TaskOptions
/**
* Vérifie si le test n'a pas échoué la suite.
* Si le test n'est pas encore fini ou a été sauté, il renverra `true`.
*/
ok(): boolean
/**
* Métadonnées personnalisées qui ont été attachées au test lors de son exécution.
*/
meta(): TaskMeta
/**
* Résultats du test. Sera `undefined` si le test n'est pas encore terminé ou a juste été collecté.
*/
result(): TestResult | undefined
/**
* Informations utiles sur le test telles que la durée, l'utilisation de la mémoire, etc.
*/
diagnostic(): TestDiagnostic | undefined
}
export type TestResult = TestResultPassed | TestResultFailed | TestResultSkipped
export interface TestResultPassed {
/**
* Le test a réussi.
*/
state: 'passed'
/**
* Erreurs qui ont été levées lors de l'exécution du test.
*
* **Remarque** : Si le test a été réessayé avec succès, les erreurs seront tout de même rapportées.
*/
errors: TestError[] | undefined
}
export interface TestResultFailed {
/**
* Le test a échoué à s'exécuter.
*/
state: 'failed'
/**
* Erreurs qui ont été levées lors de l'exécution du test.
*/
errors: TestError[]
}
export interface TestResultSkipped {
/**
* Le test a été sauté avec le drapeau `only`, `skip` ou `todo`.
* Vous pouvez voir lequel a été utilisé dans l'option `mode`.
*/
state: 'skipped'
/**
* Les tests sautés n'ont pas d'erreurs.
*/
errors: undefined
}
export interface TestDiagnostic {
/**
* La quantité de mémoire utilisée par le test en octets.
* Cette valeur n'est disponible que si le test a été exécuté avec le drapeau `logHeapUsage`.
*/
heap: number | undefined
/**
* Le temps qu'il a fallu pour exécuter le test en ms.
*/
duration: number
/**
* Le temps en ms lorsque le test a commencé.
*/
startTime: number
/**
* Le nombre de fois que le test a été réessayé.
*/
retryCount: number
/**
* Le nombre de fois que le test a été répété comme configuré par l'option `repeats`.
* Cette valeur peut être inférieure si le test a échoué pendant la répétition et aucun `retry` n'est configuré.
*/
repeatCount: number
/**
* Si le test a réussi lors d'un deuxième réessai.
*/
flaky: boolean
}

TestSuite

TestSuite représente une seule suite qui contient des tests et d’autres suites.

declare class TestSuite {
readonly type = 'suite'
/**
* Instance de tâche.
* @experimental L'API de tâche publique est expérimentale et ne suit pas semver.
*/
readonly task: RunnerTestSuite
/**
* Le projet associé au test.
*/
readonly project: TestProject
/**
* Référence directe au fichier de test où la suite est définie.
*/
readonly file: TestFile
/**
* Nom de la suite.
*/
readonly name: string
/**
* Nom complet de la suite incluant toutes les suites parentes séparées par `>`.
*/
readonly fullName: string
/**
* Identifiant unique.
* Cet ID est déterministe et sera le même pour la même suite lors de plusieurs exécutions.
* L'ID est basé sur le nom du projet, le chemin du fichier et la position de la suite.
*/
readonly id: string
/**
* Emplacement dans le fichier où la suite a été définie.
* Les emplacements ne sont collectés que si `includeTaskLocation` est activé dans la config.
*/
readonly location: { line: number; column: number } | undefined
/**
* Collection de suites et tests qui font partie de cette suite.
*/
readonly children: TaskCollection
/**
* Options avec lesquelles la suite a été initiée.
*/
readonly options: TaskOptions
}

TestFile

TestFile représente un fichier unique qui contient des suites et des tests.

declare class TestFile extends SuiteImplementation {
readonly type = 'file'
/**
* Instance de tâche.
* @experimental L'API de tâche publique est expérimentale et ne suit pas semver.
*/
readonly task: RunnerTestFile
/**
* Collection de suites et tests qui font partie de ce fichier.
*/
readonly children: TestCollection
/**
* Il s'agit généralement d'un chemin de fichier Unix absolu.
* Cela peut être un identifiant virtuel si le fichier n'est pas sur le disque.
* Cette valeur correspond à l'identifiant `ModuleGraph` de Vite.
*/
readonly moduleId: string
/**
* Informations utiles sur le fichier telles que la durée, l'utilisation de la mémoire, etc.
* Si le fichier n'a pas encore été exécuté, toutes les valeurs de diagnostic retourneront `0`.
*/
diagnostic(): FileDiagnostic
}
export interface FileDiagnostic {
/**
* Le temps qu'il a fallu pour importer et initier un environnement.
*/
environmentSetupDuration: number
/**
* Le temps qu'il a fallu à Vitest pour configurer le système de test (exécuteur, mocks, etc.).
*/
prepareDuration: number
/**
* Le temps qu'il a fallu pour importer le fichier de test.
* Cela comprend l'importation de tout ce qui se trouve dans le fichier et l'exécution des rappels de suite.
*/
collectDuration: number
/**
* Le temps qu'il a fallu pour importer le fichier de configuration.
*/
setupDuration: number
/**
* Durée accumulée de tous les tests et hooks dans le fichier.
*/
duration: number
}

TestCollection

TestCollection représente une collection de suites et de tests. Elle fournit également des méthodes utiles pour itérer sur elle-même.

declare class TestCollection {
/**
* Renvoie le test ou la suite à un index spécifique dans le tableau.
*/
at(index: number): TestCase | TestSuite | undefined
/**
* Le nombre de tests et de suites dans la collection.
*/
size: number
/**
* Renvoie la collection sous forme de tableau pour une manipulation plus facile.
*/
array(): (TestCase | TestSuite)[]
/**
* Filtre toutes les suites qui font partie de cette collection et de ses enfants.
*/
allSuites(): IterableIterator<TestSuite>
/**
* Filtre tous les tests qui font partie de cette collection et de ses enfants.
*/
allTests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>
/**
* Filtre uniquement les tests qui font partie de cette collection.
*/
tests(state?: TestResult['state'] | 'running'): IterableIterator<TestCase>
/**
* Filtre uniquement les suites qui font partie de cette collection.
*/
suites(): IterableIterator<TestSuite>;
[Symbol.iterator](): IterableIterator<TestSuite | TestCase>
}

Par exemple, vous pouvez itérer sur tous les tests à l’intérieur d’un fichier en appelant testFile.children.allTests() :

function onFileCollected(testFile: TestFile): void {
console.log('collecte des tests dans', testFile.moduleId)
// itérer sur tous les tests et suites dans le fichier
for (const task of testFile.children.allTests()) {
console.log('collecté', task.type, task.fullName)
}
}

TestProject

TestProject est un projet associé au fichier. Chaque test et suite à l’intérieur de ce fichier fera référence au même projet.

Le projet est utile pour obtenir la configuration ou le contexte fourni.

declare class TestProject {
/**
* L'instance vitest globale.
* @experimental L'API publique de Vitest est expérimentale et ne suit pas semver.
*/
readonly vitest: Vitest
/**
* Le projet d'espace de travail auquel ce projet de test est associé.
* @experimental L'API publique de Vitest est expérimentale et ne suit pas semver.
*/
readonly workspaceProject: WorkspaceProject
/**
* Configuration de projet résolue.
*/
readonly config: ResolvedProjectConfig
/**
* Configuration globale résolue. S'il n'y a pas de projets d'espace de travail, cela sera le même que `config`.
*/
readonly globalConfig: ResolvedConfig
/**
* Configuration projet sérialisée. C'est la config que les tests reçoivent.
*/
get serializedConfig(): SerializedConfig
/**
* Le nom du projet ou une chaîne vide si non défini.
*/
name(): string
/**
* Contexte personnalisé fourni au projet.
*/
context(): ProvidedContext
/**
* Fournir un contexte personnalisable sérialisable au projet. Ce contexte sera disponible pour les tests une fois qu'ils s'exécutent.
*/
provide<T extends keyof ProvidedContext & string>(key: T, value: ProvidedContext[T]): void
}

Rapporteurs Exportés

vitest est livré avec quelques rapporteurs intégrés que vous pouvez utiliser immédiatement.

Rapporteurs intégrés :

  1. BasicReporter
  2. DefaultReporter
  3. DotReporter
  4. JsonReporter
  5. VerboseReporter
  6. TapReporter
  7. JUnitReporter
  8. TapFlatReporter
  9. HangingProcessReporter

Rapporteurs Abstraits de Base :

  1. BaseReporter

Rapporteurs d’Interface :

  1. Reporter