任务元数据
WARNING
Vitest 暴露了实验性的私有 API。重大变更可能不遵循语义化版本规范(semver),使用时请固定 Vitest 的版本。
如果您正在开发自定义报告器或使用 Vitest Node.js API,您可能会发现将不同上下文中执行的测试数据传递到报告器或自定义 Vitest 处理程序非常有用。
为了实现这一点,依赖测试上下文是不可行的,因为它无法被序列化。
但是,使用 Vitest,您可以利用每个任务(测试套件或测试用例)上可用的 meta
属性,在测试与 Node.js 进程之间共享数据。需要注意的是,这种通信是单向的,因为 meta
属性只能在测试上下文中修改。在 Node.js 上下文中所做的任何更改,在测试中是不可见的。
您可以在测试上下文,或套件任务的 beforeAll
/afterAll
钩子中设置 meta
属性。
afterAll((suite) => {
suite.meta.done = true
})
test('custom', ({ task }) => {
task.meta.custom = 'some-custom-handler'
})
测试完成后,Vitest 将使用 RPC 向 Node.js 进程发送包含结果和 meta
的任务数据。要拦截和处理此任务数据,您可以利用报告器实现中提供的 onTaskUpdate
方法:
// custom-reporter.js
export default {
// 可按需拦截数据包
onTaskUpdate(packs) {
const [id, result, meta] = packs[0]
},
// 'onFinished' 中每个任务都包含 meta
onFinished(files) {
files[0].meta.done === true
files[0].tasks[0].meta.custom === 'some-custom-handler'
}
}
WARNING
如果多个测试在短时间内完成,Vitest 可能会同时发送多个任务数据。
BEWARE
Vitest 使用不同的方法与 Node.js 进程通信。
- 如果 Vitest 在 worker 线程中运行测试,它将通过 message port 发送数据。
- 如果 Vitest 使用子进程,数据将作为序列化的 Buffer 通过
process.send
API 发送。 - 如果 Vitest 在浏览器中运行测试,数据将使用 flatted 包进行字符串化。
通常的规则是,可以发送几乎所有类型的数据,除了函数、Promise、正则表达式(v8.stringify
无法序列化,但您可以发送字符串版本并在 Node.js 进程中自行解析)和其他不可序列化的数据。但允许存在循环引用。
此外,请确保在设置 Error properties 之前先序列化它们。
您还可以在测试运行结束后,从 Vitest 状态获取此信息:
const vitest = await createVitest('test')
await vitest.start()
vitest.state.getFiles()[0].meta.done === true
vitest.state.getFiles()[0].tasks[0].meta.custom === 'some-custom-handler'
在使用 TypeScript 时,您也可以扩展类型定义:
declare module 'vitest' {
interface TaskMeta {
done?: boolean
custom?: string
}
}