Golden Test — co to jest, jak działa snapshot-testowanie i zastosowanie

Autor: IT Sectr Opublikowano: 2026-04-10 Czas czytania: 9 min

Golden Test (snapshot-test, testowanie wzorcowe) — metoda wizualnego testowania UI, w której aktualny render komponentu porównywany jest z wcześniej zapisanym obrazem wzorcowym (plik golden). Jeśli zmiany pikseli przekraczają zadany próg, test kończy się niepowodzeniem i generuje obraz diff. Deweloper przegląda diff i albo akceptuje zmiany (aktualizuje golden), albo naprawia błąd. Więcej w artykule Meta Engineering o Paparazzi.

Najważniejsze

  • Golden Test — porównanie aktualnego UI z obrazem wzorcowym w celu wykrycia regresji wizualnych
  • Obraz diff — w przypadku niezgodności golden-test generuje diff z podświetleniem zmienionych pikseli
  • Android — Paparazzi i Roborazzi do screenshot-testowania komponentów compose i view
  • iOS — SwiftSnapshotTesting (pointfree.co) i iOSSnapshotTestCase od Uber dla SwiftUI i UIKit
  • Integracja CI — golden-testy uruchamiane są na CI i kończą się niepowodzeniem przy nieoczekiwanych zmianach UI

Czym jest Golden Test i jak działa?

Golden Test — to zautomatyzowane sprawdzanie wyglądu komponentu poprzez porównanie piksel po pikselu z wzorcem. Proces: (1) deweloper lub tester tworzy pierwszy zrzut komponentu — to jest „złoty“ (wzorzec). (2) Plik golden jest zapisywany w repozytorium obok testu. (3) Przy kolejnych uruchomieniach test renderuje komponent ponownie i porównuje z zapisanym golden. (4) Jeśli obrazy są zgodne — test jest zielony. Jeśli się różnią — test jest czerwony z diffem. Decyzja: albo zmiany są oczekiwane (aktualizujemy golden), albo to błąd.

Jak generowany jest golden — biblioteka renderuje komponent w buforze pozuekranowym (Android: Canvas, iOS: UIGraphicsImageRenderer) bez rzeczywistego wyświetlacza. Oznacza to, że golden-testy działają na CI bez emulatora ekranu (virtual display), co przyspiesza wykonanie. Paparazzi na Android używa Layoutlib z Android Studio — tego samego silnika, co Layout Editor. iOSSnapshotTestCase używa renderowania UIKit do CGImage. Rezultat — plik PNG o stałym rozmiarze.

Rozmiar plików golden i zarządzanie przechowywaniem

Pliki golden — zrzut PNG jednego ekranu (1080x1920) zajmuje 200-800 KB w zależności od złożoności. Dla projektu z 500 golden-testami to ~100-400 MB w repozytorium. Rozwiązania: (1) przechowywać golden w Git LFS. (2) Używać kompresji PNG (pngcrush, oxipng). (3) Przechowywać golden w osobnym storage (S3) i pobierać przy budowie. W IT Sectr przechowujemy golden w Git LFS z progiem 1 MB na plik — to wystarcza dla 90% testów.

Flaky golden tests i ich rozwiązanie

Flaky golden tests — główny problem golden-testów. Różne GPU, wersje czcionek i antyaliasing dają mikro-różnice w pikselach. Rozwiązania: threshold (dopuszczalny procent różniących się pikseli), fuzzy comparison (rozmyte porównanie) i uruchamianie na identycznych agentach CI (taki sam GPU, OS, wersja emulatora). W Paparazzi używane jest porównanie pixel-perfect, dlatego agenci CI muszą być identyczni.

Golden Test vs Screenshot Test: jaka jest różnica?

Golden Test — to rodzaj screenshot-testowania ze stałym wzorcem. Termin „złoty“ oznacza, że wzorzec został zatwierdzony (zaakceptowany) przez zespół i przechowywany w repozytorium. Każda zmiana obrazu wymaga świadomej decyzji dewelopera: zaktualizować golden lub poprawić kod. Golden Test działa na poziomie pojedynczych komponentów (Composable, UIView) i nie wymaga rzeczywistego urządzenia.

Screenshot Test — szersze pojęcie. Screenshot-test może przechwytywać cały ekran z rzeczywistymi danymi, nawigacją, paskiem stanu systemu i animacjami. Screenshot-testy często uruchamiane są na rzeczywistych urządzeniach lub emulatorach przez UI Automator (Android) lub XCUITest (iOS). Golden-testy działają w środowisku unit-test (JVM, XCTest) bez emulatora i przechwytują tylko pojedynczy komponent.

CechaGolden TestScreenshot Test
PoziomKomponent/Composable/ViewCały ekran
ŚrodowiskoUnit-test (bufor pozuekranowy)Urządzenie/Emulator
Szybkość50-200 ms na test2-30 sekund na test
AnimacjeNie są obsługiwaneSą obsługiwane (z pauzami)
CI bez GPUDziała (Layoutlib)Wymaga emulatora
Trudność konfiguracjiNiskaWysoka (Emulator/Device Farm)
FlakinessŚrednia (różne GPU)Wysoka (emulator, czas)

Strategia pokrycia: golden vs screenshot

Golden vs Screenshot — golden-testy do sprawdzania pojedynczych komponentów UI (przycisk, karta, dialog) przy każdym commicie. Screenshot-testy — do weryfikacji E2E całych ekranów przed wydaniem. Golden-testy dają szybką informację zwrotną deweloperowi, screenshot-testy — pewność integralności całej aplikacji. W IT Sectr używamy golden-testów dla Pull Request (3-5 minut), a screenshot-testów — nightly (30-60 minut).

Paparazzi i Roborazzi: snapshot-testowanie na Android

Paparazzi — biblioteka od Cash App (Square), która renderuje Android View i Jetpack Compose komponenty do PNG bez emulatora. Używa Layoutlib (tego samego silnika, co Android Studio Preview). Konfiguracja: podłączyć wtyczkę Gradle, napisać test z @Test i @RunWith(PaparazziRule::class), wywołać paparazzi.snapshot(view). Paparazzi nie obsługuje animacji, wideo i Real Device — tylko statyczny render komponentów.

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

// Golden test dla komponentu Compose
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 — alternatywa dla Paparazzi z obsługą Compose, View i porównywania obrazów. Różnica: Roborazzi działa przez Robolectric i obsługuje threshold (procent dopuszczalnej różnicy pikseli). Zmniejsza to flakiness przy różnych GPU na CI. Roborazzi potrafi również tworzyć animacje GIF zmian (przed/po/diff), co jest wygodne do code review. Format plików golden: PNG + metadane JSON.

Aktualizacja golden — po celowej zmianie UI deweloper usuwa stare pliki golden i uruchamia testy z flagą record. Paparazzi tworzy od nowa wszystkie pliki golden. Następnie deweloper commituje nowe golden razem ze zmianą kodu. W Code Review recenzent widzi diff starych i nowych golden. Jeśli zmiany są zatwierdzone — PR jest mergowany. Jeśli nie — deweloper poprawia kod i ponownie uruchamia testy. Nigdy nie aktualizuj golden automatycznie na CI — tylko lokalnie.

SwiftSnapshotTesting i iOSSnapshotTestCase na iOS

SwiftSnapshotTesting — biblioteka od pointfree.co, twórców Composable Architecture. Obsługuje UIView, UIViewController, CALayer i SwiftUI View. Zasada: assertSnapshot(matching: view, as: .image). Przy pierwszym uruchomieniu golden tworzony jest automatycznie. Przy kolejnych — porównywany. Jeśli różnica przekracza dopuszczalną — test kończy się niepowodzeniem. SwiftSnapshotTesting działa przez UIGraphicsImageRenderer, który jest kompatybilny z 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 (dawniej FBSnapshotTestCase) — biblioteka od Uber dla UIKit. W przeciwieństwie do SwiftSnapshotTesting, iOSSnapshotTestCase wymaga określenia rozmiaru ekranu i orientacji. Pliki golden — PNG w folderze ReferenceImages. Zaleta: działa z UIKit bez SwiftUI i obsługuje iOS 12+. Wada: nie aktualizuje golden automatycznie — trzeba uruchomić z flagą record. SwiftSnapshotTesting jest bardziej nowoczesny i zalecany dla nowych projektów.

Device-specific golden — pliki golden różnią się dla różnych rozmiarów ekranów i orientacji. Standardowe podejście: nazywać golden jako TestName@3x~iPhone14.png. SwiftSnapshotTesting automatycznie dodaje sufiks urządzenia, jeśli podano parametr .image(on: .iPhoneSe). Na Android Paparazzi używa DeviceConfig do ustawienia rozmiaru. Przechowuj golden dla każdego obsługiwanego device form factor osobno. Nie używaj jednego golden dla różnych rozmiarów — to doprowadzi do flaky testów.

Praca z plikami golden w CI i zarządzanie aktualizacjami

CI pipeline — golden-testy powinny być uruchamiane przy każdym Pull Request. Jeśli test kończy się niepowodzeniem, CI pokazuje obraz diff jako artefakt budowania. Deweloper przegląda diff i podejmuje decyzję. Ważne: pliki golden wygenerowane na CI nigdy nie są commitowane automatycznie. Tylko lokalne generowanie przez dewelopera po celowej zmianie. GitHub Actions i GitLab CI obsługują ładowanie artefaktów (png, html) do przeglądania diff w przeglądarce.

Rozmiar repozytorium — pliki golden szybko rosną. 500 testów = 100-400 MB PNG. Rozwiązania: (1) Git LFS — każdy golden przechowywany w LFS, klonowany tylko przy checkout. (2) Przechowywać golden w osobnym repozytorium i podłączać jako submoduł. (3) S3 + buforowanie — golden na S3, CI pobiera tylko zmienione pliki po sumie kontrolnej. W IT Sectr używamy Git LFS z track *.png filter=lfs diff=lfs merge=lfs text=false. Lokalnie golden leżą w src/test/goldens/.

Code Review golden — zwykły git diff nie pokazuje zmian PNG. Rozwiązania: (1) GitHub otwiera obrazy PNG po kliknięciu. (2) Używać Review Apps, gdzie golden-diff jest widoczny w przeglądarce. (3) Generować raport HTML z kolumnami przed/po/diff. Paparazzi tworzy raport HTML z trzema kolumnami: actual, expected, diff. Raport jest dołączany do artefaktów CI. Recenzenci przeglądają raport bez pobierania plików lokalnie.

Kiedy aktualizować golden — tylko po świadomej zmianie UI. Zmiana czcionki, koloru, odstępu, ikony — golden powinien być zaktualizowany. Dodanie nowego przycisku, przestawienie elementów — golden powinien być zaktualizowany. Poprawka błędu zmieniająca wygląd — golden powinien być zaktualizowany. Refaktoryzacja bez zmiany UI — golden nie powinien być aktualizowany. Jeśli golden zmienia się bez zmiany kodu UI — to flaky test spowodowany środowiskiem, szukaj przyczyny w agentach CI lub wersjach zależności.

Często zadawane pytania

Czym Golden Test różni się od Screenshot Test?

Golden Test — snapshot-test na poziomie komponentu w środowisku unit-test (szybki, bez emulatora). Screenshot Test — przechwytywanie całego ekranu na urządzeniu lub emulatorze (wolny, ale realistyczny). Golden działa z buforem pozuekranowym, screenshot — z rzeczywistym wyświetlaczem. Golden nadaje się do CI przy każdym commicie, screenshot — do nightly przed wydaniem.

Jak radzić sobie z flaky golden-testami?

Główne przyczyny: (1) Różne GPU na CI — używaj identycznych agentów CI. (2) Różne wersje czcionek — ustal wersję OS. (3) Różny anti-aliasing — skonfiguruj threshold (Roborazzi, iOSSnapshotTestCase). (4) Animacje — wyłączaj animacje w testach. (5) Elementy systemowe (pasek stanu) — używaj bezramkowego device config. Paparazzi nie jest podatny na flakiness dzięki Layoutlib.

Czy można używać Golden Test z Jetpack Compose?

Tak. Paparazzi ma wbudowaną obsługę Compose przez paparazzi.snapshot { }. Roborazzi również obsługuje Compose. W iOS SwiftSnapshotTesting działa z SwiftUI przez UIHostingController. Komponenty Compose są renderowane przez Layoutlib, SwiftUI — przez UIKit. Ograniczenie: nie są obsługiwane animacje Compose i SwiftUI — golden-test przechwytuje tylko stan początkowy.

Jak automatycznie zaakceptować zmiany golden?

Nigdy nie automatyzuj akceptowania golden na CI. Tylko lokalnie: deweloper usuwa stare pliki golden z katalogu i uruchamia testy z flagą record (Paparazzi: record=true, SwiftSnapshotTesting: record=true). Pliki golden są odtwarzane. Deweloper przegląda każdy golden pod kątem poprawności, commituje zmiany wraz z kodem. Automatyczne akceptowanie na CI doprowadzi do przeoczenia błędów UI.

Czy Golden Test spowalnia budowanie?

Golden-testy są szybsze niż testy instrumentalne (UI Automator, XCUITest). Jeden golden-test wykonuje się w 50-200 ms (Paparazzi: 100-150 ms na średnim MacBook Pro). 500 golden-testów = 25-100 sekund. Porównaj z screenshot-testami przez emulator: 5-30 sekund na test. Golden-testy nie spowalniają budowania: 100 testów = ~15 sekund, co jest akceptowalne dla weryfikacji pre-merge.

Podsumowanie

  • Golden Test — wizualne testowanie komponentów UI poprzez porównanie z wzorcowym obrazem PNG
  • Proces — renderowanie komponentu w buforze pozuekranowym, porównanie piksel po pikselu, diff przy niezgodności
  • Android — Paparazzi (Compose/View, Layoutlib) i Roborazzi (Compose/View, threshold, Robolectric)
  • iOS — SwiftSnapshotTesting (pointfree) i iOSSnapshotTestCase od Uber dla UIKit i SwiftUI
  • CI Pipeline — golden-testy przy każdym PR, artefakty diff, tylko lokalna aktualizacja golden
  • Git LFS — obowiązkowy do przechowywania plików PNG (100-400 MB na 500 testów)
  • Flakiness — związany z GPU, czcionkami i anti-aliasingiem; rozwiązywany przez threshold i identycznych agentów CI

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również