自定义测试池
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 中看到一个从头开始构建的简单测试池示例,该示例不运行测试,而是将它们标记为已收集。