skip to content

You own the testing standards for a large frontend codebase that has accumulated several hundred committed snapshots across component tests. How would you decide where snapshot testing genuinely earns its place, and how would you retire the rest without stopping feature work?

level: principalimportance: should knowfreq 33%

answer

  1. settle it with evidence, not taste
  2. churn without intent means no signal
  3. small, stable, tedious to hand-write
  4. stop the inflow first
  5. convert on contact, never regenerate

basics

~20 s

Judge each snapshot by evidence: has its failure ever caught something a human wanted to know? Keep the small, stable, hard-to-hand-write captures where any change deserves review; ban new broad ones so the inflow stops, and convert the rest on contact instead of in a dedicated rewrite.

solid answer

~50 s

I would start from evidence rather than philosophy. Snapshot history is queryable: for each baseline, how often did it change, and did those changes accompany PRs that intended to change output? Baselines that move constantly alongside unrelated refactors have never been evidence, and baselines that have not moved in a year cost nothing. That splits the estate into keep, retire, and ignore. The keep set is small, stable, tedious-to-hand-write values where any difference deserves a look — generated stylesheets, formatted output, normalized data shapes, a primitive's markup contract. Then I would stop the inflow first: a written standard that new tests state their claim in explicit assertions, enforced in review, so the problem stops growing. Retirement happens on contact — whoever makes a snapshot go red converts or deletes that test rather than regenerating it — plus one deliberate pruning commit for obsolete baselines. No freeze, no rewrite project.

go deeper

for a junior

Know that a snapshot is worth keeping when the captured value is small, stable, and something you would not want to type out by hand, and that a snapshot nobody reviews proves nothing.

for a middle

Be able to argue the keep-or-retire call for one specific test: name what it claims, whether its diff is judgeable, and what explicit assertions would replace it.

for a senior

Demonstrate that you would gather evidence from snapshot churn history before changing policy, and that you can preserve the deletion coverage broad snapshots were providing while removing them.

for a principal

Own the sequencing and the enforcement: stop the inflow with a written standard backed by a real gate, migrate on contact rather than in a freeze, define how success is measured a year out, and state the exception cases explicitly so teams do not invent their own.

## Decide with evidence, not taste Arguments about snapshot testing usually run on taste, which is why they never resolve. The way to settle it inside one organisation is to ask what these particular snapshots have actually done. Two questions produce most of the answer: 1. **How often does each baseline change?** Version-control history over the snapshot files gives this directly. 2. **When it changed, was the change intended?** Sample the PRs. If the PR set out to change rendered output, the snapshot did its job — it forced a review of the new output. If the PR was a refactor, a dependency bump, or a styling change, the snapshot produced churn. A third, sharper question if the data exists: has any snapshot failure ever been the thing that caught a bug before release? Teams usually remember the one or two cases. If nobody can name any, that is the finding. This reframes the discussion from "are snapshots good" to "here is what ours have cost and returned", which is an argument a team can act on. ## The keep criteria A snapshot earns its place when all of the following hold: - **The value is small enough that a diff is judgeable.** If a reviewer cannot decide in under a minute whether the new baseline is right, the assertion is not being made by a human. - **It is stable.** It moves only when behaviour moves — not on class-name churn, layout wrappers, or unrelated child edits. - **It is tedious or error-prone to hand-write.** Formatted currency and date output, a generated stylesheet or token file, a normalized data structure, a long error-message catalogue. If you would happily write the expectation by hand, write it by hand — that is a better test. - **Any change deserves human attention.** This is the real qualifier. Snapshots are a good fit for "nothing here should move without someone noticing", and a bad fit for anything else. Everything else — the whole-page component captures that make up most large estates — fails at least one criterion, usually the first two. ## Stop the inflow before draining the pool The common mistake is to open a migration project. It competes with feature work, gets half-finished, and leaves the codebase with two conventions and no standard. Sequence it the other way: 1. **Publish the standard.** One page: what a component test must assert explicitly, where a snapshot is permitted, and the maximum size that is reviewable. Concrete rules, not principles. 2. **Enforce at the boundary.** Review is where this holds. Optional supports: an ownership rule on `__snapshots__` directories so a designated reviewer sees baseline changes, and a build that fails rather than writes missing snapshots — Jest's `--ci` flag, and Vitest's refusal to create new snapshots in a CI environment. 3. **Convert on contact.** The rule that carries the migration: when a snapshot goes red, the person who broke it either writes the explicit assertions the test's name implies, or deletes the test — never regenerates. High-churn tests are exactly the worthless ones, and they convert themselves fastest. 4. **One deliberate pruning commit** for baselines orphaned by renamed and deleted tests, isolated so the deletion is reviewable on its own. 5. **Leave the quiet ones alone.** A snapshot that has not changed in a year is imposing no review cost. Deleting it is work with no return. Let attrition handle it. ## What you are trading Be honest about the cost in the interview. Broad snapshots do buy something real: they notice deletions and unexpected structural changes that no targeted assertion was written to catch. Removing them removes that net. The mitigation is to keep a small number of compact derived-value snapshots — visible headings, table cell text, the props handed to a chart — which preserve the deletion signal at a fraction of the noise. You are also trading a fast way to add tests for a slower one. Explicit assertions take longer to write. The return is that they state intent, so the next maintainer learns something from reading them, and their failures name the broken behaviour instead of showing a diff. ## The judgment being assessed The interviewer is checking three things: that you can retire a practice on evidence rather than fashion; that you know a standard without an enforcement point is a wish; and that you can sequence a large migration so it rides along with existing work rather than requiring a freeze. An answer that is only "snapshots are bad, we removed them" misses all three.

  • How do you enforce a rule like "no new page-level snapshots" without hand-policing every pull request?
    Put the pressure where the change lands. Review is the primary gate, backed by an ownership rule so baseline changes route to a reviewer who cares, and by a build that refuses to write missing snapshots so nothing is baselined silently. A written standard makes the review comment cheap to give — it becomes a pointer rather than an argument, which is what keeps it from decaying.
  • How would you know a year later whether the change worked?
    Track two numbers: how many baselines change per release, and how many of those changes accompany a PR that intended to change output. Success is the first falling sharply while the ratio of intended changes rises. If the count fell only because tests were deleted and nothing replaced them, you traded churn for blindness, and the regression escape rate will say so.
  • A team argues that snapshots are the only affordable way to test their legacy area, since writing explicit assertions there is expensive. How do you respond?
    Accept it as a real constraint and scope it. In an area with no ownership and no ongoing change, a broad snapshot is a cheap tripwire and its churn cost is near zero because nobody touches the code. Write that exception into the standard with its condition — legacy, frozen, no active development — so it is a deliberate exemption rather than a precedent other teams cite.

saying these in an interview costs you the question

  • Argues the case on philosophy without measuring what the snapshots did
  • Launches a dedicated migration project competing with feature work
  • Bans snapshots outright with no replacement for deletion coverage
  • Writes a standard with no enforcement point in review or CI
  • Spends effort deleting stable baselines that cost nothing

context