Кастомный пул
WARNING
Это расширенный API. Если вы просто хотите запустить тесты, вам, вероятно, это не нужно. Он в основном используется авторами библиотек.
Vitest запускает тесты в пулах. По умолчанию доступны следующие пулы:
threadsдля запуска тестов с использованиемnode:worker_threads(изоляция обеспечивается новым контекстом воркера)forksдля запуска тестов с использованиемnode:child_process(изоляция обеспечивается новым процессомchild_process.fork)vmThreadsдля запуска тестов с использованиемnode:worker_threads(изоляция обеспечивается модулемvmвместо нового контекста воркера)browserдля запуска тестов с использованием браузерных провайдеровtypescriptдля проверки типов в тестах
Вы можете предоставить свой собственный пул, указав путь к файлу:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
// по умолчанию будет запускать каждый файл в кастомном пуле
pool: './my-custom-pool.ts',
// вы можете предоставить параметры, используя объект `poolOptions`
poolOptions: {
myCustomPool: {
customProperty: true,
},
},
// вы также можете указать пул для подмножества файлов
poolMatchGlobs: [['**/*.custom.test.ts', './my-custom-pool.ts']],
},
});API
Файл, указанный в опции pool, должен экспортировать функцию (возможно, асинхронную), принимающую интерфейс Vitest в качестве первого аргумента. Эта функция должна возвращать объект, соответствующий интерфейсу 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>;
}Функция вызывается только один раз (если конфигурация сервера не была обновлена). Рекомендуется инициализировать все необходимое для тестов внутри этой функции и повторно использовать это при каждом вызове runTests.
Vitest вызывает runTests, когда запланированы новые тесты для запуска. Он не будет вызывать его, если массив files пуст. Первый аргумент - это массив кортежей, где первый элемент - ссылка на проект рабочей области, а второй - абсолютный путь к тестовому файлу. Файлы сортируются с использованием sequencer до вызова runTests. Хотя это маловероятно, один и тот же файл может встретиться дважды, но он всегда будет связан с другим проектом. Это обеспечивается конфигурацией vitest.workspace.ts.
Vitest будет ждать завершения runTests, прежде чем завершить запуск тестов (то есть, событие onFinished будет сгенерировано только после того, как runTests завершится).
При использовании кастомного пула вам потребуется самостоятельно загружать тестовые файлы и обрабатывать их результаты. Для этого можно обратиться к vitest.state (особенно важны collectFiles и updateTasks). Vitest использует функцию startTests из пакета @vitest/runner для этой цели.
Vitest вызовет collectTests, если вызывается vitest.collect или vitest list через команду CLI. Он работает так же, как runTests, но вам не нужно запускать обратные вызовы тестов, нужно только сообщать об их задачах, вызвав vitest.state.collectFiles(files).
Для организации взаимодействия между различными процессами вы можете создать объект методов, используя createMethodsRPC из vitest/node, и использовать любой подходящий способ связи. Например, чтобы использовать WebSockets с birpc, вы можете написать что-то вроде этого:
import { createBirpc } from 'birpc';
import { parse, stringify } from 'flatted';
import { createMethodsRPC, WorkspaceProject } 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,
});
}Чтобы убедиться, что каждый тест собран, вы должны вызвать ctx.state.collectFiles и сообщить об этом репортерам Vitest:
async function runTests(project: WorkspaceProject, tests: string[]) {
// ... запуск тестов, результаты помещаются в "files" и "tasks"
const methods = createMethodsRPC(project);
await methods.onCollected(files);
// большинство репортеров используют результаты, обновляемые в "onTaskUpdate"
await methods.onTaskUpdate(tasks);
}Пример простой реализации можно посмотреть в pool/custom-pool.ts.