自定义测试池
WARNING
这是一个高级且非常底层的 API。如果您只是想运行测试,您可能不需要它。它主要供库作者使用。
Vitest 在测试池中运行测试。默认情况下,有以下几种内置测试池:
threads:使用node:worker_threads运行测试,通过新的 Worker 上下文实现隔离。forks:使用node:child_process运行测试,通过新的child_process.fork进程实现隔离。vmThreads:使用node:worker_threads运行测试,但通过vm模块而非新的 Worker 上下文实现隔离。browser:在浏览器环境中运行测试。typescript:用于测试的类型检查。
您可以通过指定文件路径来创建自己的自定义测试池:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
// 默认情况下,所有测试文件都将使用此自定义测试池运行
pool: './my-custom-pool.ts',
// 您可以使用 `poolOptions` 对象为自定义测试池提供配置选项
poolOptions: {
myCustomPool: {
customProperty: true,
},
},
},
});如果您需要在不同的测试池中运行测试,请使用 projects 功能:
export default defineConfig({
test: {
projects: [
{
extends: true,
test: {
pool: 'threads',
},
},
],
},
});API
pool 选项中指定的文件应导出一个函数(可以是异步函数),该函数接受 Vitest 接口作为其第一个参数。此函数需要返回一个符合 ProcessPool 接口的对象:
import type { ProcessPool, TestSpecification } from 'vitest/node';
export interface ProcessPool {
name: string;
runTests: (
files: TestSpecification[],
invalidates?: string[]
) => Promise<void>;
collectTests: (
files: TestSpecification[],
invalidates?: string[]
) => Promise<void>;
close?: () => Promise<void>;
}该函数只会被调用一次(除非服务器配置已更新)。通常,最佳实践是在该函数内部初始化测试所需的所有内容,并在后续调用 runTests 时重用它们。
当有新的测试计划运行时,Vitest 会调用 runTests。如果 files 数组为空,则不会调用该函数。runTests 的第一个参数是 TestSpecifications 的数组。在调用 runTests 之前,文件会通过 sequencer 进行排序。同一个文件可能(尽管不常见)会出现两次,但每次都将属于不同的项目——这是通过 projects 配置实现的。
Vitest 会等待 runTests 执行完成后才结束一次运行(即,它只会在 runTests Promise 解析后发出 onFinished 事件)。
如果您使用自定义测试池,您必须自己提供测试文件及其结果。您可以参考 vitest.state 来实现此功能(其中最重要的是 collectFiles 和 updateTasks)。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, TestProject } from 'vitest/node';
function createRpc(project: TestProject, wss: WebSocketServer) {
return createBirpc(createMethodsRPC(project), {
post: msg => wss.send(msg),
on: fn => wss.on('message', fn),
serialize: stringify,
deserialize: parse,
});
}您可以在 pool/custom-pool.ts 中看到一个从头开始构建的简单测试池示例,该示例不运行测试,而是将它们标记为已收集。