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.