•
Drizz raises $2.7M in seed funding •
•
Featured on Forbes
•
Drizz raises $2.7M in seed funding •
•
Featured on Forbes
Logo
Schedule a demo
Blog page
>
Snapshot Testing for Mobile Apps Explained

Snapshot Testing for Mobile Apps Explained

Snapshot testing explained for mobile teams. How it works on iOS and Android, Jest vs native snapshot tools, where it fits in your test pyramid, and when to skip it.
Author:
Asad Abrar
Posted on:
June 22, 2026
Read time:

Snapshot testing captures a reference image (or data representation) of your UI component, then compares future renders against that reference to detect unintended changes. If  output changes,  test fails. You review  diff and either approve  new snapshot or fix  regression.

On web, snapshot testing is built into frameworks like Jest and Vitest. On mobile, it works differently. iOS teams use swift-snapshot-testing. Android teams use Paparazzi. Both capture screenshots of UI components and compare them pixel by pixel against stored references.

What is snapshot testing?

Snapshot testing compares  current output of a component against a previously stored reference. If  output matches,  test passes. If it doesn't,  test fails and shows you  difference.

The snapshot can be different things depending on your framework:

  • In Jest and Vitest,  snapshot is a serialized text representation of a React component's render tree (not a visual image)
  • In swift snapshot testing for iOS,  snapshot is an actual screenshot of  rendered component
  • In Paparazzi for Android,  snapshot is a screenshot captured without running an emulator (JVM-based rendering)
  • In visual regression tools like Percy or Applitools,  snapshot is a full-page screenshot compared using intelligent diffing algorithms

The concept is  same across all of them: store a reference, compare against it, flag changes. What is snapshot testing at its core? It's change detection for your UI.

How does snapshot testing work on mobile?

Mobile snapshot testing has two distinct approaches: component-level snapshots and screen-level snapshots.

Component-level snapshots capture individual UI components (a button, a card, a form input) in isolation. You render  component with specific props or data, capture  output, and store it as  reference. This is fast because you don't need to launch  full app.

On iOS, component-level snapshot testing uses swift-snapshot-testing:

func testLoginButton() {
    let button = LoginButton(state: .active)
    assertSnapshot(of: button, as: .image)
}

‍

On Android, Paparazzi handles  same thing without an emulator:

@Test
fun loginButton() {
    paparazzi.snapshot {
        LoginButton(state = ButtonState.Active)
    }
}

‍

Screen level snapshots capture entire screens of  app. These are slower because they require more setup (navigate to  screen, populate data, handle dynamic content). But they catch layout issues that component level snapshots miss, like overlapping elements, broken scroll behavior, or misaligned sections.

Companies like OpenAI, Airbnb, Twitter, and Revolut use snapshot testing as a required step in their mobile CI/CD pipeline, according to discussions in  Mobile Native Foundation community.

How does Jest snapshot testing relate to mobile?

Jest snapshot testing and native mobile snapshot testing solve  same problem in different ways.

Jest / Vitest (web) swift-snapshot-testing (iOS) Paparazzi (Android)
Snapshot format Serialized text (render tree) Image (screenshot) Image (screenshot)
Runs on Node.js Xcode / macOS JVM (no emulator needed)
What it catches Structural changes in components Visual changes in rendered UI Visual changes in rendered UI
Speed Milliseconds Seconds Seconds
False positive risk Low (text comparison is precise) Medium (pixel shifts, font rendering) Medium (rendering differences across JVM versions)

Jest testing with snapshots compares  text structure of your component tree. A jest snapshot test fails when  rendered HTML structure changes, not when a pixel shifts. This makes jest snapshot testing fast and deterministic, but it doesn't catch visual bugs.

Mobile snapshot testing compares actual rendered images. This catches visual bugs (wrong color, misaligned element, truncated text) but is more sensitive to non functional changes like anti aliasing differences between OS versions.

For React Native teams, you can use both: testing jest for structural snapshots of your JavaScript components (using react testing library snapshot utilities), and snapshot testing ios or Android screenshot testing for  native render output. The two layers catch different things. Libraries like snapshottest ( Python equivalent) follow  same concept for backend snapshot testing. The snapshot testing react ecosystem has matured to  point where most component libraries include snapshot tests by default.

Where does snapshot testing fit in  test pyramid?

Snapshot testing sits between unit tests and full E2E tests. It's faster than E2E because it doesn't need a running app or real device (for component-level snapshots). It's slower than unit tests because it involves rendering and image comparison.

Here's how it fits alongside other testing types:

  • Unit tests catch logic bugs (calculations, data transformations, state management)
  • Snapshot tests catch visual regressions (unintended UI changes in individual components)
  • Integration tests catch boundary bugs (API contracts, data flow between modules)
  • E2E tests catch workflow bugs (full user flows across  app)

Snapshot testing covers a gap that unit tests and E2E tests leave open: verifying that your UI components look correct without running  full app. A unit test can verify that a ViewModel produces  right data. A snapshot test verifies that  view renders that data correctly.

When does snapshot testing cause more problems than it solves?

Snapshot testing has real limitations that most guides downplay. On mobile, these show up fast.

Approval fatigue. When your snapshot suite has 500+ snapshots and an OS update changes font rendering by half a pixel, all 500 fail. Your team has to review and approve each one. After  third bulk approval, people start approving without looking. The safety net stops working because nobody trusts it anymore.

iOS version sensitivity. A new iOS version can change system font rendering, navigation bar height, or status bar layout. These changes break every snapshot even though your app is fine. Teams on swift-snapshot-testing report spending hours re-approving snapshots after Xcode updates.

Dynamic content. Snapshots assume static output. If your component shows a timestamp, user-generated content, or randomized data,  snapshot will differ on every run. You need to mock or freeze dynamic content before capturing, which adds fixture complexity.

Diminishing returns on screen-level snapshots. Component-level snapshots are high-value because they're fast and targeted. Screen-level snapshots are expensive to maintain because any change anywhere on  screen triggers a failure. Most teams get more value from 50 component snapshots than from 10 full-screen snapshots.

Snapshot testing vs visual regression testing: what's  difference?

These terms get used interchangeably, but they're different.

Snapshot testing captures a reference and compares against it exactly (pixel-perfect or structure-exact). Any change, intentional or not, fails  test. The developer reviews and approves or rejects.

Visual regression testing captures screenshots and compares them using intelligent diffing that tolerates minor rendering differences. It focuses on catching unintended visual changes while ignoring irrelevant pixel shifts. Tools like Percy, Applitools, and Drizz use AI-based comparison instead of pixel-perfect matching.

The practical difference: snapshot testing is binary (match or no match). Visual regression testing is probabilistic (how much did it change, and does  change matter?).

For mobile teams, visual regression testing is often more practical because pixel-perfect comparison generates too many false positives across device configurations. Vision AI approaches (like Drizz) take this further by testing  full app on real devices and adapting to UI changes visually, combining visual regression detection with functional test execution.

What does a practical mobile snapshot strategy look like?

A fintech app team uses snapshot testing at two levels:

Component snapshots (200 tests, run on every PR): each reusable UI component (buttons, cards, input fields, transaction rows) has snapshots in both light and dark mode. These run in CI using Paparazzi (Android) and swift-snapshot-testing (iOS). Build time impact: 45 seconds. These catch unintended changes to  design system.

E2E visual checks (40 tests, run nightly): full user flows run on real devices through Drizz. Vision AI compares screen state at each step against expected behavior. These catch layout bugs that component snapshots miss (broken scrolling, overlapping elements, platform-specific rendering issues). No pixel-perfect comparison, so no false positives from OS level rendering changes.

The team skipped screen level snapshots entirely. Component snapshots catch design system regressions. E2E visual checks catch full-screen layout bugs. The gap between those two layers was too expensive to fill with traditional snapshot testing.

How should you get started with snapshot testing on mobile?

Start with your design system components. If your app has a component library (buttons, cards, inputs, list items), add snapshot tests for each component in its default states. This gives you  highest value per test because design system changes ripple across  entire app.

Pick  right tool for your platform:

Platform Tool How it works
iOS (SwiftUI/UIKit) swift-snapshot-testing Captures images of rendered views in Xcode tests
Android (Compose/Views) Paparazzi JVM-based rendering, no emulator needed
React Native (JS layer) Jest with snapshot serializer Text-based structural snapshots
Cross-platform visual Drizz, Percy, Applitools Screenshot comparison on real devices

Then follow these rules:

  • Snapshot individual components, not full screens (less maintenance, fewer false positives)
  • Freeze dynamic content before capturing (timestamps, user data, random elements)
  • Set a review threshold. If more than 20 snapshots fail at once, investigate  root cause before bulk-approving
  • Run component snapshots on every PR. Run visual regression checks nightly on real devices with a tool like Drizz

Snapshot testing is a strong layer in your mobile test automation strategy. It catches  visual regressions that unit tests miss and does it faster than E2E tests. The trap is over relying on pixel-perfect comparison across too many screens. Keep snapshots targeted, use Vision AI for full-screen checks, and your team catches visual bugs without drowning in false positives.

‍

FAQs

What is snapshot testing?

Snapshot testing captures a reference image or data representation of a UI component, then compares future renders against that reference. If  output changes,  test fails. You review  diff and approve  change or fix  regression. It's change detection for your UI.

How does snapshot testing work on iOS?

iOS snapshot testing uses  swift-snapshot-testing library. You render a SwiftUI or UIKit component in a test, capture its visual output as an image, and store it as  reference. On  next run,  library compares  new render against  stored reference. Any visual difference triggers a test failure.

How does snapshot testing work on Android?

Android snapshot testing commonly uses Paparazzi, a JVM-based tool from Square. Paparazzi renders Compose or View components without an emulator, captures screenshots, and compares them against references. Because it runs on  JVM, it's fast and CI-friendly.

What is  difference between snapshot testing and visual regression testing?

Snapshot testing compares against a reference exactly (pixel-perfect). Any change fails  test. Visual regression testing uses intelligent diffing that tolerates minor rendering differences and focuses on meaningful visual changes. Visual regression testing produces fewer false positives on mobile because it handles OS-level rendering variations.

What are  limitations of snapshot testing on mobile?

The main limitations are approval fatigue (bulk-approving hundreds of snapshots after OS updates), sensitivity to non-functional rendering changes (font anti-aliasing, status bar height), dynamic content that requires mocking, and  high maintenance cost of screen-level snapshots. Component-level snapshots avoid most of these issues.

Should you use Jest snapshot testing for mobile?

If you're building with React Native, Jest snapshot testing catches structural changes in your JavaScript component tree. It's fast and deterministic but doesn't catch visual rendering bugs. Pair it with native snapshot testing (swift-snapshot-testing or Paparazzi) or visual regression testing for complete coverage.

About the Author:

Asad Abrar
Co-founder & CEO, Drizz
Ex-Coinbase PM and IIT Kharagpur grad killing flaky mobile tests by day, and obsessing over F1 lap timings by night.
Schedule a demo