install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/codex/test-snapshot-patterns" ~/.claude/skills/intense-visions-harness-engineering-test-snapshot-patterns-b13af8 && rm -rf "$T"
manifest:
agents/skills/codex/test-snapshot-patterns/SKILL.mdsource content
Test Snapshot Patterns
Use snapshot testing selectively for stable outputs, knowing when to avoid it
When to Use
- Testing serialized output (JSON, HTML, error messages) that should not change unexpectedly
- Verifying component render output for regression detection
- Capturing complex object shapes that are tedious to assert manually
- NOT for rapidly changing UI or non-deterministic output
Instructions
- Basic snapshot:
it('serializes user data correctly', () => { const user = formatUser({ id: '1', name: 'Alice', email: 'alice@test.com' }); expect(user).toMatchSnapshot(); });
First run creates the snapshot file. Subsequent runs compare against it.
- Inline snapshots — store the expected value in the test file:
it('formats the error message', () => { const error = formatError({ code: 404, resource: 'User' }); expect(error).toMatchInlineSnapshot(`"User not found (404)"`); });
Vitest/Jest auto-fills the inline snapshot on first run.
- Snapshot specific properties:
it('creates a user with generated fields', () => { const user = createUser({ name: 'Alice' }); expect(user).toMatchSnapshot({ id: expect.any(String), createdAt: expect.any(Date), }); });
This snapshots the structure but uses matchers for non-deterministic fields.
- Update snapshots when intentional changes occur:
vitest --update # or vitest -u
Review the diff before committing updated snapshots.
- Prefer inline snapshots for small values — they are easier to review in PRs:
it('generates correct SQL', () => { const query = buildQuery({ table: 'users', where: { role: 'admin' } }); expect(query).toMatchInlineSnapshot(` "SELECT * FROM users WHERE role = 'admin'" `); });
- Snapshot file-based output for large payloads:
it('generates correct API response', () => { const response = buildResponse(testData); expect(response).toMatchSnapshot(); // Stored in __snapshots__/ });
-
Avoid snapshots for:
- UI components that change frequently (use specific assertions instead)
- Non-deterministic output (timestamps, random IDs)
- Very large objects (snapshots become unreadable)
- Behavior testing (use explicit assertions)
-
Good snapshot candidates:
- Serialization formats (JSON output, GraphQL schema)
- Error messages and validation output
- Configuration generation
- CLI output formatting
Details
Snapshot testing captures the serialized output of a value and compares it against a stored reference. It is a regression detection tool — it tells you when output changes, but not whether the change is correct.
Snapshot workflow:
- First run: snapshot is created and stored (in
or inline)__snapshots__/ - Subsequent runs: output is compared against the stored snapshot
- On mismatch: test fails with a diff
- To accept the change: run with
flag and review the diff--update
Snapshot hygiene:
- Review snapshot diffs in PRs as carefully as code changes
- Delete snapshots for removed tests — stale snapshots cause confusion
- Keep snapshots small — large snapshots are rubber-stamped in review
- Use
for values under 5 lines — inline snapshots are easier to reviewtoMatchInlineSnapshot
vs toMatchSnapshot
:toMatchInlineSnapshot
- File-based: stored separately, good for large output, harder to review in PRs
- Inline: stored in the test file, easy to review, best for small values
Trade-offs:
- Snapshots catch unintentional changes with minimal effort — but also flag intentional changes, requiring update ceremonies
- Large snapshot files are easy to create — but become "approve without reading" in code review
- Inline snapshots are reviewable — but clutter test files with literal output
- Snapshot tests are fast to write — but can mask poor test design (asserting everything instead of specific behavior)
Source
https://vitest.dev/guide/snapshot.html
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.