可取消的测试资源
测试运行过程中可能占用一些资源,测试停止后这些资源不会随之释放。无论是 fetch、子进程、文件流还是轮询,它们都无法感知 Vitest 已取消测试,导致工作进程只能被动等待它们自行结束 Vitest 会在测试超时超过 timeout 限制、在 --bail 模式下另一个测试失败,或有人在终端按下 Ctrl+C 时取消测试。
测试上下文提供了 signal 3.2.0+ ,它会在上述所有情况下触发。将它传递给任何接受 AbortSignal 的对象,当 Vitest 取消测试时对应的资源就会被释放。
示例
ts
import { test } from 'vitest'
test('stop request when test times out', async ({ signal }) => {
await fetch('/heavy-resource', { signal })
}, 2000)如果请求未在 2 秒内完成,fetch 会抛出 AbortError,而不会让测试挂起直到操作结束。
其他接受 AbortSignal 的 Web API
fetchaddEventListener,传递{ signal }会在中止时移除监听器ReadableStream.pipeTo- 像 Node.js API
fs.readFile,child_process.spawn,和setTimeout或setInterval,它们都接受{ signal } - 任何调用
signal.throwIfAborted()或监听'abort'的代码
传递信号
将测试的信号接入你自己的工具函数,使取消操作向下传递:
ts
async function pollUntilReady(url: string, signal: AbortSignal) {
while (!signal.aborted) {
const res = await fetch(url, { signal })
if (res.ok) {
return
}
await new Promise(r => setTimeout(r, 200))
}
signal.throwIfAborted()
}
test('worker becomes ready', async ({ signal }) => {
await pollUntilReady('http://localhost:4000/health', signal)
}, 5000)