---
name: snapshot-testing
description: Snapshot testing with file, inline, and file snapshots
---

# Snapshot Testing

Snapshot tests capture output and compare against stored references.

## Basic Snapshot

```ts
import { expect, test } from "vitest";

test("snapshot", () => {
  const result = generateOutput();
  expect(result).toMatchSnapshot();
});
```

First run creates `.snap` file:

```js
// __snapshots__/test.spec.ts.snap
exports["snapshot 1"] = `
{
  "id": 1,
  "name": "test"
}
`;
```

## Inline Snapshots

Stored directly in test file:

```ts
test("inline snapshot", () => {
  const data = { foo: "bar" };
  expect(data).toMatchInlineSnapshot();
});
```

Vitest updates the test file:

```ts
test("inline snapshot", () => {
  const data = { foo: "bar" };
  expect(data).toMatchInlineSnapshot(`
    {
      "foo": "bar",
    }
  `);
});
```

## File Snapshots

Compare against explicit file:

```ts
test("render html", async () => {
  const html = renderComponent();
  await expect(html).toMatchFileSnapshot("./expected/component.html");
});
```

## Snapshot Hints

Add descriptive hints:

```ts
test("multiple snapshots", () => {
  expect(header).toMatchSnapshot("header");
  expect(body).toMatchSnapshot("body content");
  expect(footer).toMatchSnapshot("footer");
});
```

## Object Shape Matching

Match partial structure:

```ts
test("shape snapshot", () => {
  const data = {
    id: Math.random(),
    created: new Date(),
    name: "test",
  };

  expect(data).toMatchSnapshot({
    id: expect.any(Number),
    created: expect.any(Date),
  });
});
```

## Error Snapshots

```ts
test("error message", () => {
  expect(() => {
    throw new Error("Something went wrong");
  }).toThrowErrorMatchingSnapshot();
});

test("inline error", () => {
  expect(() => {
    throw new Error("Bad input");
  }).toThrowErrorMatchingInlineSnapshot(`[Error: Bad input]`);
});
```

## Updating Snapshots

```bash
# Update all snapshots
vitest -u
vitest --update

# In watch mode, press 'u' to update failed snapshots
```

## Custom Serializers

Add custom snapshot formatting:

```ts
expect.addSnapshotSerializer({
  test(val) {
    return val && typeof val.toJSON === "function";
  },
  serialize(val, config, indentation, depth, refs, printer) {
    return printer(val.toJSON(), config, indentation, depth, refs);
  },
});
```

Or via config:

```ts
// vitest.config.ts
defineConfig({
  test: {
    snapshotSerializers: ["./my-serializer.ts"],
  },
});
```

## Snapshot Format Options

```ts
defineConfig({
  test: {
    snapshotFormat: {
      printBasicPrototype: false, // Don't print Array/Object prototypes
      escapeString: false,
    },
  },
});
```

## Concurrent Test Snapshots

Use context's expect:

```ts
test.concurrent("concurrent 1", async ({ expect }) => {
  expect(await getData()).toMatchSnapshot();
});

test.concurrent("concurrent 2", async ({ expect }) => {
  expect(await getOther()).toMatchSnapshot();
});
```

## Snapshot File Location

Default: `__snapshots__/<test-file>.snap`

Customize:

```ts
defineConfig({
  test: {
    resolveSnapshotPath: (testPath, snapExtension) => {
      return testPath.replace("__tests__", "__snapshots__") + snapExtension;
    },
  },
});
```

## Key Points

- Commit snapshot files to version control
- Review snapshot changes in code review
- Use hints for multiple snapshots in one test
- Use `toMatchFileSnapshot` for large outputs (HTML, JSON)
- Inline snapshots auto-update in test file
- Use context's `expect` for concurrent tests

<!--
Source references:
- https://vitest.dev/guide/snapshot.html
- https://vitest.dev/api/expect.html#tomatchsnapshot
-->
