Pool personalizzato
WARNING
Questa è un'API avanzata. Se stai semplicemente eseguendo dei test, probabilmente non ne hai bisogno. È utilizzata principalmente dagli autori di librerie.
Vitest esegue i test in pool. Per impostazione predefinita, sono disponibili diversi pool:
threads
per eseguire i test usandonode:worker_threads
(l'isolamento è fornito da un nuovo contesto worker)forks
per eseguire i test usandonode:child_process
(l'isolamento è fornito con un nuovo processochild_process.fork
)vmThreads
per eseguire i test usandonode:worker_threads
(ma l'isolamento è fornito con il modulovm
invece di un nuovo contesto worker)browser
per eseguire i test usando fornitori di browsertypescript
per eseguire la verifica dei tipi sui test
Puoi fornire un pool personalizzato specificando un percorso di file:
import { defineConfig } from 'vitest/config';
// ---cut---
export default defineConfig({
test: {
// eseguirà ogni file usando un pool personalizzato per impostazione predefinita
pool: './my-custom-pool.ts',
// puoi fornire opzioni tramite l'oggetto `poolOptions`
poolOptions: {
myCustomPool: {
customProperty: true,
},
},
// puoi anche specificare il pool per un sottoinsieme di file
poolMatchGlobs: [['**/*.custom.test.ts', './my-custom-pool.ts']],
},
});
API
Il file specificato nell'opzione pool
deve esportare una funzione (può essere asincrona) che accetta l'interfaccia Vitest
come primo argomento. Questa funzione deve restituire un oggetto che implementa l'interfaccia ProcessPool
:
import { ProcessPool, WorkspaceProject } from 'vitest/node';
export interface ProcessPool {
name: string;
runTests: (
files: [project: WorkspaceProject, testFile: string][],
invalidates?: string[]
) => Promise<void>;
close?: () => Promise<void>;
}
La funzione viene invocata una sola volta (a meno che la configurazione del server non venga aggiornata). È generalmente consigliabile inizializzare tutto ciò che serve per i test all'interno di questa funzione e riutilizzarlo quando viene chiamato runTests
.
Vitest chiama runTests
quando sono pianificati nuovi test da eseguire. Non lo chiamerà se files
è vuoto. Il primo parametro è un array di tuple: il primo elemento è un riferimento a un progetto workspace, mentre il secondo è un percorso assoluto a un file di test. I file vengono ordinati usando sequencer
prima che venga chiamato runTests
. È possibile (anche se improbabile) avere lo stesso file due volte, ma avrà sempre un progetto diverso: questo è implementato tramite la configurazione vitest.workspace.ts
.
Vitest attenderà che runTests
termini l'esecuzione prima di generare l'evento onFinished
(ovvero, solo dopo che la Promise restituita da runTests
è stata risolta).
Se stai usando un pool personalizzato, dovrai gestire l'esecuzione dei file di test e la gestione dei relativi risultati. Puoi fare riferimento a vitest.state
per questo (le parti più importanti sono collectFiles
e updateTasks
). Vitest usa la funzione startTests
dal pacchetto @vitest/runner
per facilitare questo processo.
Per comunicare tra processi diversi, puoi creare un oggetto methods
usando createMethodsRPC
da vitest/node
e usare qualsiasi forma di comunicazione tu preferisca. Ad esempio, per usare WebSockets con birpc
puoi scrivere un codice simile:
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,
});
}
Per assicurarti che ogni test venga raccolto, chiameresti ctx.state.collectFiles
e segnaleresti i risultati ai reporter di Vitest:
async function runTests(project: WorkspaceProject, tests: string[]) {
// ... esecuzione dei test, inserire in "files" e "tasks"
const methods = createMethodsRPC(project);
await methods.onCollected(files);
// la maggior parte dei reporter dipende dall'aggiornamento dei risultati in "onTaskUpdate"
await methods.onTaskUpdate(tasks);
}
Puoi vedere un semplice esempio in pool/custom-pool.ts.