Golden Test — What It Is, How Snapshot Testing Works and Its Application

Author: IT Sectr Published: 2026-04-10 Reading time: 9 min

Golden Test (snapshot test, reference testing) is a method of visual UI testing where the current component render is compared with a pre-saved reference image (golden file). If pixel changes exceed a set threshold, the test fails and generates a diff image. The developer reviews the diff and either accepts the changes (updates the golden file) or fixes the bug. Read more in the Meta Engineering article about Paparazzi.

Key Takeaways

  • Golden Test — comparing the current UI with a reference image to detect visual regressions
  • Diff Image — when a golden test fails, it generates a diff highlighting changed pixels
  • Android — Paparazzi and Roborazzi for screenshot testing of Compose and View components
  • iOS — SwiftSnapshotTesting (pointfree.co) and iOSSnapshotTestCase by Uber for SwiftUI and UIKit
  • CI Integration — golden tests run on CI and fail on unexpected UI changes

What Is Golden Test and How Does It Work?

Golden Test is an automated check of a component’s visual appearance by pixel-by-pixel comparison with a reference. The process: (1) the developer or tester creates the first snapshot of the component — this is the “golden” (reference). (2) The golden file is saved in the repository next to the test. (3) On subsequent runs, the test re-renders the component and compares it with the saved golden. (4) If the images match — the test passes. If they differ — the test fails with a diff. Decision: either the changes are expected (update the golden) or it’s a bug.

How the golden is generated — the library renders the component into an off-screen buffer (Android: Canvas, iOS: UIGraphicsImageRenderer) without a real display. This means golden tests work on CI without an emulator screen (virtual display), speeding up execution. Paparazzi on Android uses Layoutlib from Android Studio — the same engine as the Layout Editor. iOSSnapshotTestCase uses UIKit rendering into a CGImage. The result is a PNG file of a fixed size.

Golden File Size and Storage Management

Golden files — a PNG snapshot of one screen (1080x1920) takes 200–800 KB depending on complexity. For a project with 500 golden tests, that’s ~100–400 MB in the repository. Solutions: (1) store golden files in Git LFS. (2) Use PNG compression (pngcrush, oxipng). (3) Store golden files on a separate storage (S3) and fetch them during build. At IT Sectr, we store golden files in Git LFS with a 1 MB per file threshold — this is enough for 90% of tests.

Flaky Golden Tests and How to Fix Them

Flaky golden tests — the main problem with golden testing. Different GPUs, font versions, and anti-aliasing produce micro-differences in pixels. Solutions: threshold (allowable percentage of differing pixels), fuzzy comparison, and running on identical CI agents (same GPU, OS, emulator version). Paparazzi uses pixel-perfect comparison, so CI agents must be identical.

Golden Test vs Screenshot Test: What’s the Difference?

Golden Test is a type of screenshot testing with a fixed reference. The term “golden” means the reference has been approved by the team and is stored in the repository. Any image change requires a conscious decision from the developer: update the golden or fix the code. Golden test works at the level of individual components (Composable, UIView) and does not require a real device.

Screenshot Test is a broader concept. A screenshot test can capture a full screen with real data, navigation, system status bar, and animations. Screenshot tests are often run on real devices or emulators via UI Automator (Android) or XCUITest (iOS). Golden tests run in a unit-test environment (JVM, XCTest) without an emulator and only capture a single component.

CharacteristicGolden TestScreenshot Test
LevelComponent/Composable/ViewFull screen
EnvironmentUnit-test (off-screen buffer)Device/Emulator
Speed50–200 ms per test2–30 seconds per test
AnimationsNot supportedSupported (with pauses)
CI without GPUWorks (Layoutlib)Requires emulator
Setup complexityLowHigh (Emulator/Device Farm)
FlakinessMedium (different GPUs)High (emulator, timing)

Coverage Strategy: Golden vs Screenshot

Golden vs Screenshot — golden tests for checking individual UI components (button, card, dialog) on every commit. Screenshot tests for E2E checks of entire screens before release. Golden tests provide fast feedback to the developer, screenshot tests provide confidence in the integrity of the entire application. At IT Sectr, we use golden tests for Pull Requests (3–5 minutes) and screenshot tests nightly (30–60 minutes).

Paparazzi and Roborazzi: Snapshot Testing on Android

Paparazzi — a library from Cash App (Square) that renders Android View and Jetpack Compose components into PNG without an emulator. It uses Layoutlib (the same engine as Android Studio Preview). Setup: add the Gradle plugin, write a test with @Test and @RunWith(PaparazziRule::class), call paparazzi.snapshot(view). Paparazzi does not support animations, video, or Real Device — only static component rendering.

kotlin
// build.gradle.kts (module)
plugins {
    id("app.cash.paparazzi") version "1.3.1"
}

// Golden test for a Compose component
class ButtonGoldenTest {

    @get:Rule
    val paparazzi = Paparazzi(
        Paparazzi.PaparazziSnapshotConfig(
            deviceConfig = DeviceConfig.PIXEL_6,
            theme = "android:Theme.Material.Light.NoActionBar"
        )
    )

    @Test
    fun primary_button() {
        paparazzi.snapshot {
            Button(
                onClick = { },
                modifier = Modifier.width(200.dp)
            ) {
                Text("Submit")
            }
        }
    }
}

Roborazzi — an alternative to Paparazzi with support for Compose, View, and image comparison. Difference: Roborazzi works through Robolectric and supports a threshold (allowable pixel difference percentage). This reduces flakiness with different GPUs on CI. Roborazzi can also create GIF animations of changes (before/after/diff), which is convenient for code review. Golden file format: PNG + JSON metadata.

Updating the golden — after an intentional UI change, the developer deletes the old golden files and runs tests with the record flag. Paparazzi recreates all golden files. Then the developer commits the new golden files along with the code change. In Code Review, the reviewer sees the diff of old and new golden files. If the changes are approved — the PR is merged. If not — the developer fixes the code and restarts the tests. Never update golden files automatically on CI — only locally.

SwiftSnapshotTesting and iOSSnapshotTestCase on iOS

SwiftSnapshotTesting — a library from pointfree.co, creators of Composable Architecture. Supports UIView, UIViewController, CALayer, and SwiftUI View. Principle: assertSnapshot(matching: view, as: .image). On first run, the golden is created automatically. On subsequent runs, it’s compared. If the difference exceeds the allowable threshold, the test fails. SwiftSnapshotTesting works through UIGraphicsImageRenderer, which is compatible with CI (Xcode Cloud, GitHub Actions).

swift
import SnapshotTesting
import XCTest

final class ProfileCardSnapshotTests: XCTestCase {

    func test_profile_card_default() {
        let card = ProfileCard(
            name: "Alice",
            avatar: UIImage.testImage(),
            badge: "Pro"
        )
        let controller = UIHostingController(rootView: card)

        assertSnapshot(
            matching: controller,
            as: .image(on: .iPhoneSe),
            record: ProcessInfo.processInfo
                .environment["RECORD"] != nil
        )
    }
}

iOSSnapshotTestCase (formerly FBSnapshotTestCase) — a library from Uber for UIKit. Unlike SwiftSnapshotTesting, iOSSnapshotTestCase requires specifying the screen size and orientation. Golden files are PNGs in the ReferenceImages folder. Advantage: works with UIKit without SwiftUI and supports iOS 12+. Disadvantage: does not update golden files automatically — must be run with the record flag. SwiftSnapshotTesting is more modern and recommended for new projects.

Device-specific golden — golden files differ for different screen sizes and orientations. The standard approach: name golden files as TestName@3x~iPhone14.png. SwiftSnapshotTesting automatically adds a device suffix if the .image(on: .iPhoneSe) parameter is specified. On Android, Paparazzi uses DeviceConfig to set the size. Store golden files for each supported device form factor separately. Do not use one golden for different sizes — this will lead to flaky tests.

Working with Golden Files in CI and Managing Updates

CI pipeline — golden tests should run on every Pull Request. If a test fails, CI shows the diff image as a build artifact. The developer reviews the diff and makes a decision. Important: golden files generated on CI are never committed automatically. Only local generation by the developer after an intentional change. GitHub Actions and GitLab CI support uploading artifacts (png, html) for viewing diffs in the browser.

Repository size — golden files grow quickly. 500 tests = 100–400 MB of PNGs. Solutions: (1) Git LFS — each golden is stored in LFS, cloned only on checkout. (2) Store golden files in a separate repository and include them as a submodule. (3) S3 + caching — golden files on S3, CI downloads only changed files by checksum. At IT Sectr, we use Git LFS with track *.png filter=lfs diff=lfs merge=lfs text=false. Locally, golden files reside in src/test/goldens/.

Code Review of golden files — regular git diff does not show PNG changes. Solutions: (1) GitHub opens PNG images on click. (2) Use Review Apps where golden diffs are visible in the browser. (3) Generate an HTML report with before/after/diff columns side by side. Paparazzi creates an HTML report with three columns: actual, expected, diff. The report is attached to CI artifacts. Reviewers view the report without downloading files locally.

When to update the golden — only after a conscious UI change. Changing a font, color, padding, icon — the golden must be updated. Adding a new button, rearranging elements — the golden must be updated. A bug fix that changes the visual appearance — the golden must be updated. Refactoring without UI changes — the golden should not change. If a golden changes without UI code changes — it’s a flaky test caused by environment, look for the cause in CI agents or dependency versions.

Frequently Asked Questions

How is Golden Test different from Screenshot Test?

Golden Test — a snapshot test at the component level in a unit-test environment (fast, no emulator). Screenshot Test — captures the full screen on a device or emulator (slower, but realistic). Golden works with off-screen buffer, screenshot works with a real display. Golden is suitable for CI on every commit, screenshot is for nightly runs before release.

How to deal with flaky golden tests?

Main causes: (1) Different GPUs on CI — use identical CI agents. (2) Different font versions — pin the OS version. (3) Different anti-aliasing — configure a threshold (Roborazzi, iOSSnapshotTestCase). (4) Animations — disable animations in tests. (5) System elements (status bar) — use a bezel-less device config. Paparazzi is not prone to flakiness due to Layoutlib.

Can Golden Test be used with Jetpack Compose?

Yes. Paparazzi has built-in Compose support via paparazzi.snapshot { }. Roborazzi also supports Compose. On iOS, SwiftSnapshotTesting works with SwiftUI through UIHostingController. Compose components are rendered via Layoutlib, SwiftUI through UIKit rendering. Limitation: Compose and SwiftUI animations are not supported — golden test captures only the initial state.

How to automatically accept golden changes?

Never automate golden acceptance on CI. Only locally: the developer deletes old golden files from the directory and runs tests with the record flag (Paparazzi: record=true, SwiftSnapshotTesting: record=true). Golden files are recreated. The developer reviews each golden for correctness, commits the changes together with the code. Automatic acceptance on CI will lead to missed UI bugs.

Do Golden Tests slow down the build?

Golden tests are faster than instrumented tests (UI Automator, XCUITest). One golden test executes in 50–200 ms (Paparazzi: 100–150 ms on an average MacBook Pro). 500 golden tests = 25–100 seconds. Compare with screenshot tests via emulator: 5–30 seconds per test. Golden tests do not slow down the build: 100 tests = ~15 seconds, which is acceptable for pre-merge checking.

Summary

  • Golden Test — visual testing of UI components by comparison with a reference PNG image
  • Process — render component in off-screen buffer, pixel-by-pixel comparison, diff on mismatch
  • Android — Paparazzi (Compose/View, Layoutlib) and Roborazzi (Compose/View, threshold, Robolectric)
  • iOS — SwiftSnapshotTesting (pointfree) and iOSSnapshotTestCase by Uber for UIKit and SwiftUI
  • CI Pipeline — golden tests on every PR, diff artifacts, only local golden updates
  • Git LFS — mandatory for storing PNG files (100–400 MB for 500 tests)
  • Flakiness — related to GPU, fonts, and anti-aliasing; solved by threshold and identical CI agents

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also