output_skills/testing/approval-tests/SKILL.md
Writes approval tests (snapshot/golden master testing) for Python, JavaScript/TypeScript, or Java. Use when verifying complex output, characterization testing legacy code, testing combinations, or working with .approved/.received files.
npx skillsauth add lexler/skill-factory approval-testsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
STARTER_CHARACTER = 📸
"A picture's worth 1000 assertions."
Approval tests verify complex output by comparing against a saved "golden master" file instead of writing individual assertions. You capture the output once, review it, approve it, and future runs compare against that approved snapshot.
You don't need to know the expected output upfront. Run the code, see what it produces, decide if it's correct. Approval is a judgment - you're confirming this is what the code should produce. Whoever writes the code reviews and approves.
Use approval tests when:
Use assertions when:
1. Write test with verify(result)
2. Run test → FAILS (no .approved file yet)
3. Creates: TestName.approved.txt (empty) + TestName.received.txt (actual output)
4. Review .received file - is this correct?
5. YES → rename/copy .received to .approved
6. Run test again → PASSES
7. Commit .approved file to version control
File naming convention:
{TestClass}.{test_method}.approved.txt ← commit this
{TestClass}.{test_method}.received.txt ← gitignore this
Critical rules:
.approved files ARE your test expectations - commit them.received files are temporary - add *.received.* to .gitignore.approved files by hand - always generate via testWhen a test fails, a diff tool opens showing approved vs received. This is how you review changes. Reporters configure which diff tool to use.
All languages follow the same pattern:
verify(result) # Basic string/object verification
verify_as_json(object) # Objects as formatted JSON
verify_all(header, items) # Collections with labels
verify_all_combinations(fn, inputs) # All input combinations
Non-deterministic data (timestamps, GUIDs) must be scrubbed before verification.
[Date1] or guid_1. Without scrubbing, tests pass locally but fail in CI.See language references for implementation details.
Detect language from project files, then read the appropriate reference for installation, quick start, core patterns, and links to deeper reference files:
pyproject.toml, setup.py, requirements.txt)package.json)pom.xml, build.gradle)verify_as_json({"items": items})Flaky tests across environments usually means unscrubbed dynamic data (timestamps, UUIDs, ports, paths).
development
Test-driven development (TDD) process used when writing code. Use whenever you are adding any new code, unless the user explicitly asks to skip TDD or the code is exploratory/spike.
development
Writes tests without mocks using Nullables. Use when writing tests, especially testing code with external I/O (HTTP, files, databases, clocks, random numbers), designing infrastructure wrappers or replacing mocking libraries.
testing
Scannable BDD tests written in domain language. Use when doing BDD.
tools
Iterative refinement through multiple passes. Use when the user asks to 'meditate on', 'distill', 'refine', or 'iterate on' something, or proactively when a problem benefits from multiple passes rather than a single attempt.