跳至内容

自定义池

警告

这是高级 API。如果您只是运行测试,您可能不需要它。它主要由库作者使用。

Vitest 在池中运行测试。默认情况下,有几个池

  • threads 使用 node:worker_threads 运行测试(隔离通过新的工作程序上下文提供)
  • forks 使用 node:child_process 运行测试(隔离通过新的 child_process.fork 进程提供)
  • vmThreads 使用 node:worker_threads 运行测试(但隔离通过 vm 模块而不是新的工作程序上下文提供)
  • browser 使用浏览器提供程序运行测试
  • typescript 对测试运行类型检查

您可以通过指定文件路径来提供自己的池

ts
export default ({
  : {
    // will run every file with a custom pool by default
    : './my-custom-pool.ts',
    // you can provide options using `poolOptions` object
    : {
      : {
        : true,
      },
    },
    // you can also specify pool for a subset of files
    : [
      ['**/*.custom.test.ts', './my-custom-pool.ts'],
    ],
  },
})

API

pool 选项中指定的文件应导出一个函数(可以是异步的),该函数接受 Vitest 接口作为其第一个选项。此函数需要返回一个与 ProcessPool 接口匹配的对象

ts
import { ProcessPool, WorkspaceProject } from 'vitest/node'

export interface ProcessPool {
  name: string
  runTests: (files: [project: WorkspaceProject, testFile: string][], invalidates?: string[]) => Promise<void>
  close?: () => Promise<void>
}

该函数只调用一次(除非服务器配置已更新),通常最好在该函数内部初始化测试所需的一切,并在调用 runTests 时重用它。

当安排新的测试运行时,Vitest 会调用 runTest。如果 files 为空,它不会调用它。第一个参数是一个元组数组:第一个元素是对工作区项目的引用,第二个元素是测试文件的绝对路径。在调用 runTests 之前,使用 sequencer 对文件进行排序。有可能(但不太可能)两次出现同一个文件,但它总是会有一个不同的项目 - 这是通过 vitest.workspace.ts 配置实现的。

Vitest 将等待 runTests 执行完毕,然后再完成运行(即,只有在 runTests 解决后才会发出 onFinished)。

如果您使用的是自定义池,您将必须自己提供测试文件及其结果 - 您可以参考 vitest.state 来实现这一点(最重要的部分是 collectFilesupdateTasks)。Vitest 使用 @vitest/runner 包中的 startTests 函数来执行此操作。

要在不同的进程之间进行通信,您可以使用 vitest/node 中的 createMethodsRPC 创建方法对象,并使用您喜欢的任何形式的通信。例如,要使用 birpc 与 WebSockets 通信,您可以编写类似以下内容

ts
import { createBirpc } from 'birpc'
import { parse, stringify } from 'flatted'
import { WorkspaceProject, createMethodsRPC } 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 报告器

ts
async function runTests(project: WorkspaceProject, tests: string[]) {
  // ... running tests, put into "files" and "tasks"
  const methods = createMethodsRPC(project)
  await methods.onCollected(files)
  // most reporters rely on results being updated in "onTaskUpdate"
  await methods.onTaskUpdate(tasks)
}

您可以在 pool/custom-pool.ts 中看到一个简单的示例。