Skip to content

pool

  • 类型: 'threads' | 'forks' | 'vmThreads' | 'vmForks'
  • 默认值: 'forks'
  • 命令行终端: --pool=threads

用于运行测试的线程池。

threads

启用多线程模式。使用线程时,无法调用 process.chdir() 等进程相关 API。某些使用原生语言编写的库(如 Prismabcryptcanvas)在多线程运行时会出现问题并导致存储器区段错误。此类情况下建议改用 forks 执行池。

forks

类似于 threads 线程池,但使用 child_process 代替 worker_threads。测试与主进程之间的通信速度不如 threads,但可以使用 process.chdir() 等进程相关 API。

vmThreads

threads 池中使用 VM 上下文,以沙箱方式运行测试。

这种方式可以加快测试速度,但 VM 模块在运行 ESM 代码 时并不稳定。此外,测试还会出现 内存泄漏。为限制内存占用,当工作线程使用的内存超过 vmMemoryLimit 时,Vitest 会将其重启。

vmThreads 中回收工作线程的开销较高

重启工作线程会产生明显的开销。在线程退出之前,Node.js 会对该线程积累的所有内存执行一次完整的垃圾回收。这项工作由进程内所有工作线程共用的一小组后台线程执行。当大型测试套件反复触及 vmMemoryLimit 时,工作线程的销毁操作会不断累积,并拖慢仍在运行测试的其他工作线程。

vmForks 则通过结束子进程完成回收,内存由操作系统负责释放。如果测试套件规模较大,需要定期回收子进程,那么即使 vmForks 与主进程之间的通信速度较慢,其整体运行速度通常仍会明显快于 vmThreads

注意

在沙箱中运行代码有一些优势(测试速度更快),但也存在一些劣势。

  • 原生模块(如 fspath 等)内的全局变量与你的测试环境中存在的全局变量不同。因此,这些原生模块抛出的任何错误都会引用一个与你的代码中使用的 Error 构造函数不同的构造函数:
ts
try {
  fs.writeFileSync('/does-not-exist')
}
catch (err) {
  console.log(err instanceof Error) // false
}
  • 导入 ES 模块会导致其被永久缓存,当存在大量上下文(测试文件)时,将引发内存泄漏问题。Node.js 目前未提供清除该缓存的 API 接口。
  • 在沙箱环境中访问全局变量 耗时更长

使用此选项时,需要注意这些问题。Vitest 团队无法解决上诉问题。

vmForks

类似于 vmThreads 线程池,但使用 child_process 代替 worker_threads。测试与主进程之间的通信不如 vmThreads 线程池快。在 vmForks 线程池中可以使用与进程相关的 API,如 process.chdir()。请注意,此线程池具有 vmThreads 中列出的相同缺陷。

vmThreads 不同,当子进程的内存占用超过 vmMemoryLimit 时,vmForks 只需结束该进程即可完成回收,因此开销要低得多。对于需要定期回收子进程的大型测试套件,建议优先使用 vmForks