Snapshot test = render component, serialize tree thành text/JSON, lưu file .snap.
- Chạy lại sau, so với snapshot cũ.
- Khác → fail.
test('Button renders correctly', () => {
const tree = render(<Button label="Submit" />).toJSON()
expect(tree).toMatchSnapshot()
})Hữu ích khi:
- Component thuần presentation (Avatar, Badge, Tag) — UI ít đổi, snapshot bắt regression vô tình.
- Lib component public — ngăn maintainer accidentally break public API shape.
- Test pure rendering không có business logic — verify "đầu ra" không thay đổi sau refactor.
Hại khi:
- False positive cao: UI legitimate đổi (đổi padding, đổi label) → snapshot fail → dev quen tay --updateSnapshot không nhìn diff → không thật sự verify gì.
- Diff không readable: snapshot dài 200 dòng → reviewer skip qua → không catch bug.
- Coverage giả: đạt 80% coverage qua snapshot không đảm bảo behavior đúng — chỉ đảm bảo render giống lần trước.
- Couple với implementation: đổi một class name → fail; refactor không ảnh hưởng UX → fail.
Quy tắc thực tế:
- Avoid snapshot cho integration test, screen-level test.
- Prefer behavior-driven test với getByRole, getByText từ RNTL.
- Nếu phải snapshot: inline snapshot (.toMatchInlineSnapshot()) — diff ngay trong code, dễ review hơn file .snap.
- Visual regression (Percy, Chromatic) tốt hơn snapshot cho UI test thực sự.
Industry trend 2026: snapshot test giảm dùng — focus vào behavior + visual regression + E2E.
A snapshot test renders a component, serializes the tree to text/JSON, and stores a .snap file.
Reruns compare against the saved snapshot — any difference fails.
test('Button renders correctly', () => {
const tree = render(<Button label="Submit" />).toJSON()
expect(tree).toMatchSnapshot()
})Helpful when:
- Pure presentation components (Avatar, Badge, Tag) — UI rarely changes, snapshots catch accidental regressions.
- Public library components — prevents maintainers from accidentally breaking the public API shape.
- Pure rendering with no business logic — verifies "output" stays stable after refactor.
Harmful when:
- High false-positive rate: legitimate UI changes (padding, label tweaks) fail snapshots → devs reflexively run --updateSnapshot without reading diffs → nothing is really verified.
- Unreadable diffs: a 200-line snapshot diff → reviewers skip it → bugs slip through.
- Fake coverage: 80% coverage via snapshots does not prove behaviour — only that rendering matches last time.
- Implementation coupling: rename a class → fail; UX-neutral refactor → fail.
Practical rule:
- Avoid snapshots for integration or screen-level tests.
- Prefer behaviour-driven tests using getByRole, getByText from RNTL.
- If you must snapshot: use inline snapshots (.toMatchInlineSnapshot()) — the diff lives in the test file and is easier to review.
- Visual regression (Percy, Chromatic) beats snapshots for real UI tests.
2026 industry trend: snapshot testing is on the decline — focus on behaviour + visual regression + E2E.