可取消的测试资源
测试可能会持有一些资源,即使测试停止了它们也不会停止。fetch、子进程、文件流、轮询循环:当 Vitest 取消测试时,这些都不会察觉,而工作线程只能在那里等待它们自行完成。当测试超过其 timeout,当另一个测试在 --bail 下失败,或者当有人在终端中按下 Ctrl+C 时,Vitest 会取消测试。
测试上下文提供了一个 signal 3.2.0+ ,它会在上述所有情况下触发。将它传递给任何接受 AbortSignal 的内容,当 Vitest 取消时,资源就会被释放。
模式
ts
import { test } from 'vitest'
test('当测试超时时停止请求', 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)