三种快照写法
基于 Vitest v4.x / Jest v30.x 编写
速查
toMatchSnapshot():外部.snap文件,存测试文件旁__snapshots__/toMatchInlineSnapshot():内联,框架自动写回测试文件的断言参数toMatchFileSnapshot(path):写到指定文件(Vitest 独有,异步须await)- 错误快照:
toThrowErrorMatchingSnapshot()/toThrowErrorMatchingInlineSnapshot() hint参数:区分同一测试内的多个快照
外部快照 toMatchSnapshot
最常用,快照存测试文件旁的 __snapshots__/<测试文件>.snap:
ts
import { expect, it } from "vitest";
it("用户列表结构", () => {
expect(getUsers()).toMatchSnapshot();
});同一测试内多次快照可用 hint 区分:
ts
expect(a).toMatchSnapshot("登录前");
expect(b).toMatchSnapshot("登录后");签名(第一个参数也可传属性匹配器,见 属性匹配器):
ts
toMatchSnapshot(propertyMatchers?: object, hint?: string): void内联快照 toMatchInlineSnapshot
快照作为字符串参数写回测试文件本身,无需 .snap:
ts
it("内联", () => {
expect({ a: 1 }).toMatchInlineSnapshot(`
{
"a": 1,
}
`);
});- 首次运行时框架自动填入快照字符串
- 适合小输出(几行内),可读性好、审查直观
- Jest 若装了 Prettier 会自动格式化内联快照;Vitest 用 AST 改写
文件快照 toMatchFileSnapshot(Vitest 独有)
把快照写到显式指定的文件,适合 HTML / SVG / CSS 等需要独立文件和语法高亮的整文件:
ts
import { expect, it } from "vitest";
it("渲染 HTML", async () => {
const html = renderHTML(/* ... */);
await expect(html).toMatchFileSnapshot("./test/basic.output.html");
});必须 await
toMatchFileSnapshot 返回 Promise。不 await 会按 expect.soft 处理——代码继续执行,到测试结束才报失败,容易漏判。
Jest 30.x 没有等价的
toMatchFileSnapshot,需第三方库手动实现。这是切换框架时要注意的差异之一。
错误快照
捕获抛出的错误消息并快照:
ts
function drink(flavor: string) {
if (flavor === "octopus") throw new Error("yuck, octopus flavor");
}
it("抛错快照", () => {
expect(() => drink("octopus")).toThrowErrorMatchingSnapshot();
});
it("抛错内联", () => {
expect(() => drink("octopus")).toThrowErrorMatchingInlineSnapshot(
`[Error: yuck, octopus flavor]`,
);
});Vitest 与 Jest 的错误格式不同
Vitest 渲染为 [Error: message](含类名),Jest 只快照消息字符串 "message"。切换框架时错误快照需重新生成。