Passer au contenu

Pool Personnalisé

Vitest exécute des tests dans des pools. Par défaut, il y a plusieurs pools :

  • threads pour exécuter des tests en utilisant node:worker_threads (l’isolation est fournie avec un nouveau contexte de travail)
  • forks pour exécuter des tests en utilisant node:child_process (l’isolation est fournie avec un nouveau processus child_process.fork)
  • vmThreads pour exécuter des tests en utilisant node:worker_threads (mais l’isolation est fournie avec le module vm au lieu d’un nouveau contexte de travail)
  • browser pour exécuter des tests en utilisant des fournisseurs de navigateur
  • typescript pour effectuer une vérification de type sur les tests

Vous pouvez fournir votre propre pool en spécifiant un chemin de fichier :

import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
// exécutera chaque fichier avec un pool personnalisé par défaut
pool: './my-custom-pool.ts',
// vous pouvez fournir des options en utilisant l'objet `poolOptions`
poolOptions: {
myCustomPool: {
customProperty: true,
},
},
// vous pouvez également spécifier un pool pour un sous-ensemble de fichiers
poolMatchGlobs: [
['**/*.custom.test.ts', './my-custom-pool.ts'],
],
},
})

API

Le fichier spécifié dans l’option pool doit exporter une fonction (peut être asynchrone) qui accepte l’interface Vitest comme première option. Cette fonction doit retourner un objet correspondant à l’interface ProcessPool :

import { ProcessPool, WorkspaceProject } from 'vitest/node'
export interface ProcessPool {
name: string
runTests: (files: [project: WorkspaceProject, testFile: string][], invalidates?: string[]) => Promise<void>
collectTests: (files: [project: WorkspaceProject, testFile: string][], invalidates?: string[]) => Promise<void>
close?: () => Promise<void>
}

La fonction n’est appelée qu’une seule fois (à moins que la configuration du serveur ne soit mise à jour), et c’est généralement une bonne idée d’initialiser tout ce dont vous avez besoin pour les tests à l’intérieur de cette fonction et de le réutiliser lorsque runTests est appelé.

Vitest appelle runTest lorsque de nouveaux tests sont programmés pour s’exécuter. Il ne l’appellera pas si files est vide. Le premier argument est un tableau de tuples : le premier élément est une référence à un projet de travail et le second est un chemin absolu vers un fichier de test. Les fichiers sont triés à l’aide de sequencer avant que runTests ne soit appelé. Il est possible (mais peu probable) d’avoir le même fichier deux fois, mais il aura toujours un projet différent - cela est mis en œuvre via la configuration vitest.workspace.ts.

Vitest attendra que runTests soit exécuté avant de terminer un run (c’est-à-dire, il émettra onFinished uniquement après que runTests soit résolu).

Si vous utilisez un pool personnalisé, vous devrez fournir les fichiers de test et leurs résultats vous-même - vous pouvez vous référer à vitest.state pour cela (les plus importants sont collectFiles et updateTasks). Vitest utilise la fonction startTests du package @vitest/runner pour cela.

Vitest appellera collectTests si vitest.collect est appelé ou si vitest list est invoqué via une commande CLI. Cela fonctionne de la même manière que runTests, mais vous n’avez pas à exécuter les rappels de test, seulement à rapporter leurs tâches en appelant vitest.state.collectFiles(files).

Pour communiquer entre différents processus, vous pouvez créer un objet de méthodes en utilisant createMethodsRPC de vitest/node, et utiliser n’importe quelle forme de communication que vous préférez. Par exemple, pour utiliser WebSockets avec birpc, vous pouvez écrire quelque chose comme ceci :

import { createBirpc } from 'birpc'
import { parse, stringify } from 'flatted'
import { WorkspaceProject, createMethodsRPC } from 'vitest/node'
function createRpc(project: WorkspaceProject, wss: WebSocketServer) {
return createBirpc(
createMethodsRPC(project),
{
post: msg => wss.send(msg),
on: fn => wss.on('message', fn),
serialize: stringify,
deserialize: parse,
},
)
}

Pour vous assurer que chaque test est collecté, vous appelleriez ctx.state.collectFiles et le rapporteriez aux reporters de Vitest :

async function runTests(project: WorkspaceProject, tests: string[]) {
// ... exécution des tests, mis dans "files" et "tasks"
const methods = createMethodsRPC(project)
await methods.onCollected(files)
// la plupart des reporters dépendent des résultats étant mis à jour dans "onTaskUpdate"
await methods.onTaskUpdate(tasks)
}

Vous pouvez voir un exemple simple dans pool/custom-pool.ts.