Pool Customizado
WARNING
Esta é uma API avançada. Se você está apenas executando testes, provavelmente não precisará disso. É usada principalmente por autores de bibliotecas.
O Vitest executa os testes em pools. Por padrão, existem vários pools:
threads
para executar testes usandonode:worker_threads
(o isolamento é fornecido com um novo contexto de worker)forks
para executar testes usandonode:child_process
(o isolamento é fornecido com um novo processochild_process.fork
)vmThreads
para executar testes usandonode:worker_threads
(mas o isolamento é fornecido com o módulovm
em vez de um novo contexto de worker)browser
para executar testes usando provedores de navegadortypescript
para executar a verificação de tipos nos testes
Você pode fornecer seu próprio pool especificando um caminho de arquivo:
import { defineConfig } from 'vitest/config';
// ---cut---
export default defineConfig({
test: {
// executará cada arquivo com um pool personalizado por padrão
pool: './my-custom-pool.ts',
// você pode fornecer opções usando o objeto `poolOptions`
poolOptions: {
myCustomPool: {
customProperty: true,
},
},
// você também pode especificar o pool para um subconjunto de arquivos
poolMatchGlobs: [['**/*.custom.test.ts', './my-custom-pool.ts']],
},
});
API
O arquivo especificado na opção pool
deve exportar uma função (que pode ser assíncrona) que aceite a interface Vitest
como seu primeiro argumento. Esta função deve retornar um objeto que corresponda à interface 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>;
}
A função é chamada apenas uma vez (a menos que a configuração do servidor tenha sido atualizada). É recomendável inicializar tudo o que você precisa para os testes dentro dessa função e reutilizá-lo quando runTests
for chamado.
O Vitest chama runTests
quando novos testes são agendados para execução. Ele não será chamado se files
estiver vazio. O primeiro argumento é um array de tuplas: o primeiro elemento é uma referência a um projeto de workspace e o segundo é um caminho absoluto para um arquivo de teste. Os arquivos são ordenados usando sequencer
antes que runTests
seja chamado. É possível (mas improvável) ter o mesmo arquivo duas vezes, mas sempre terá um projeto diferente - isso é implementado através da configuração vitest.workspace.ts
.
O Vitest esperará até que runTests
seja executado antes de finalizar uma execução (ou seja, ele emitirá onFinished
somente após a resolução de runTests
).
Se você estiver usando um pool personalizado, terá que fornecer os arquivos de teste e seus resultados. Você pode referenciar vitest.state
para isso (os mais importantes são collectFiles
e updateTasks
). O Vitest usa a função startTests
do pacote @vitest/runner
para fazer isso.
Para se comunicar entre diferentes processos, você pode criar um objeto de métodos com createMethodsRPC
de vitest/node
e usar qualquer forma de comunicação que preferir. Por exemplo, para usar WebSockets com birpc
você pode escrever algo como isto:
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,
});
}
Para garantir que cada teste seja coletado, você deve chamar ctx.state.collectFiles
e reportar isso aos reporters do Vitest:
async function runTests(project: WorkspaceProject, tests: string[]) {
// ... executando testes, colocando em "files" e "tasks"
const methods = createMethodsRPC(project);
await methods.onCollected(files);
// a maioria dos reporters dependem dos resultados sendo atualizados em "onTaskUpdate"
await methods.onTaskUpdate(tasks);
}
Você pode ver um exemplo simples em pool/custom-pool.ts.