自定义 pool
WARNING
这是一个高级 API。如果你只是想运行测试,你可能不需要它。它主要供库作者使用。
Vitest 在 pool 中运行测试。默认情况下,有以下几种 pool:
threads:使用node:worker_threads运行测试(通过新的 worker 上下文提供隔离)。forks:使用node:child_process运行测试(通过新的child_process.fork进程提供隔离)。vmThreads:使用node:worker_threads运行测试(但隔离由vm模块而不是新的 worker 上下文提供)。browser:使用浏览器提供程序运行测试。typescript:使用 typescript 对测试进行类型检查。
您可以通过指定文件路径来提供自定义 pool:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
// 默认情况下,将使用自定义 pool 运行每个文件
pool: './my-custom-pool.ts',
// 您可以使用 `poolOptions` 对象提供选项
poolOptions: {
myCustomPool: {
customProperty: true,
},
},
// 您还可以为文件子集指定 pool
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 为空,则不会调用该函数。第一个参数是一个元组数组:第一个元素是对 workspace project 的引用,第二个元素是测试文件的绝对路径。在调用 runTests 之前,文件会使用 sequencer 进行排序。同一个文件可能会出现两次(尽管可能性不大),但每次出现时它都属于不同的项目——这是通过 vitest.workspace.ts 配置实现的。
Vitest 会等待 runTests 执行完成后才结束运行(即,它只会在 runTests Promise resolve 后才发出 onFinished 事件)。
如果您正在使用自定义 pool,您将必须自己处理测试文件的运行及其结果的收集——可以参考 vitest.state 来获取相关信息。Vitest 使用来自 @vitest/runner 包的 startTests 函数来实现这一点。
如果调用了 vitest.collect 或者通过 CLI 命令执行了 vitest list,Vitest 就会调用 collectTests。它的工作方式与 runTests 类似,但是你不需要运行测试回调函数,只需要通过调用 vitest.state.collectFiles(files) 来报告测试任务即可。
要在不同的进程之间进行通信,您可以使用 vitest/node 中的 createMethodsRPC 创建方法对象,并使用您喜欢的任何形式的通信方式。例如,要将 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 reporters:
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 中看到一个简单的例子。