Golden Test — шта је то, како ради snapshot-тестирање и примена

Аутор: IT Sectr Објављено: 2026-04-10 Време читања: 9 мин

Golden Test (snapshot-тест, еталонско тестирање) — метод визуелног тестирања UI при којем се тренутни рендер компоненте пореди са унапред сачуваном еталонском сликом (golden-фајлом). Ако пикселске промене премаше задати праг, тест пада и генерише diff-слику. Програмер прегледа diff и или прихвата промене (ажурира golden) или исправља баг. Више у чланку Meta Engineering о Paparazzi.

Главно

  • Golden Test — поређење тренутног UI са еталонском сликом за откривање визуелних регресија
  • Diff-слика — при несовпадању golden-тест генерише диф са истакнутим измењеним пикселима
  • Android — Paparazzi и Roborazzi за screenshot-тестирање compose и view компоненти
  • iOS — SwiftSnapshotTesting (pointfree.co) и iOSSnapshotTestCase од Uber за SwiftUI и UIKit
  • CI интеграција — golden-тестови се покрећу на CI и падају при неочекиваним променама UI

Шта је Golden Test и како ради?

Golden Test — то је аутоматизована провера изгледа компоненте поређењем пиксел по пиксел са еталоном. Процес: (1) програмер или тестер прави први снимак компоненте — то је „golden“ (еталон). (2) Golden фајл се чува у репозиторијуму поред теста. (3) При наредним покретањима тест рендерује компоненту поново и пореди са сачуваним golden. (4) Ако се слике поклапају — тест је зелен. Ако се разликују — тест је црвен са дифом. Одлука: или су промене очекиване (ажурирамо golden), или је то баг.

Како се генерише golden — библиотека рендерује компоненту ван екрана (Android: Canvas, iOS: UIGraphicsImageRenderer) без правог дисплеја. То значи да golden-тестови раде на CI без емулатора екрана (virtual display), што убрзава извршење. Paparazzi на Android користи Layoutlib из Android Studio — исти мотор као Layout Editor. iOSSnapshotTestCase користи UIKit рендеровање у CGImage. Резултат — PNG фајл фиксне величине.

Величина golden-фајлова и управљање складиштењем

Golden-фајлови — PNG снимак једног екрана (1080x1920) заузима 200-800 KB у зависности од сложености. За пројекат са 500 golden-тестова то је ~100-400 MB у репозиторијуму. Решења: (1) чувати golden у Git LFS. (2) Користити PNG компресију (pngcrush, oxipng). (3) Чувати golden на одвојеном складишту (S3) и преузимати при изградњи. У IT Sectr чувамо golden у Git LFS са прагом од 1 MB по фајлу — то је довољно за 90% тестова.

Flaky golden тестови и њихово решење

Flaky golden тестови — главни проблем golden-тестова. Различити GPU, верзије фонтова и антиалиасинг дају микро-разлике у пикселима. Решења: threshold (дозвољени проценат различитих пиксела), fuzzy comparison (замагљено поређење) и покретање на истим CI агентима (исти GPU, OS, верзија емулатора). У Paparazzi се користи pixel-perfect поређење, зато CI агенти морају бити идентични.

Golden Test vs Screenshot Test: у чему је разлика?

Golden Test — то је врста screenshot-тестирања са фиксним еталоном. Термин „golden“ значи да је еталон одобрен (прихваћен) од стране тима и чува се у репозиторијуму. Свака промена слике захтева свесну одлуку програмера: ажурирати golden или исправити код. Golden Test ради на нивоу појединачних компоненти (Composable, UIView) и не захтева прави уређај.

Screenshot Test — шири појам. Screenshot-тест може да сними цео екран са правим подацима, навигацијом, системским статус-баром и анимацијама. Screenshot-тестови се често покрећу на правим уређајима или емулаторима преко UI Automator (Android) или XCUITest (iOS). Golden-тестови раде у unit-test окружењу (JVM, XCTest) без емулатора и снимају само појединачну компоненту.

КарактеристикаGolden TestScreenshot Test
НивоКомпонента/Composable/ViewЦео екран
ОкружењеUnit-test (ван екрана)Уређај/Емулатор
Брзина50-200 ms по тесту2-30 секунди по тесту
АнимацијеНису подржанеПодржане (са паузама)
CI без GPUРади (Layoutlib)Захтева емулатор
Сложеност подешавањаНискаВисока (Емулатор/Device Farm)
FlakinessСредња (различити GPU)Висока (емулатор, време)

Стратегија покрића: golden vs screenshot

Golden vs Screenshot — golden-тестови за проверу појединачних UI компоненти (дугме, картица, дијалог) при сваком комиту. Screenshot-тестови — за E2E проверу целих екрана пре издања. Golden-тестови дају брзу повратну информацију програмеру, screenshot-тестови — сигурност у интегритет целе апликације. У IT Sectr користимо golden-тестове за Pull Request (3-5 минута), а screenshot-тестове — nightly (30-60 минута).

Paparazzi и Roborazzi: snapshot-тестирање на Android

Paparazzi — библиотека од Cash App (Square) која рендерује Android View и Jetpack Compose компоненте у PNG без емулатора. Користи Layoutlib (исти мотор као Android Studio Preview). Подешавање: повезати Gradle додатак, написати тест са @Test и @RunWith(PaparazziRule::class), позвати paparazzi.snapshot(view). Paparazzi не подржава анимације, видео и Real Device — само статички рендер компоненти.

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

// Golden test для 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 — алтернатива Paparazzi са подршком за Compose, View и поређење слика. Разлика: Roborazzi ради преко Robolectric и подржава threshold (проценат дозвољеног одступања пиксела). То смањује flakiness при различитим GPU на CI. Roborazzi такође може да креира GIF анимацију промена (пре/после/diff), што је згодно за преглед кода. Формат golden-фајлова: PNG + JSON метаподаци.

Ажурирање golden — после намерне промене UI, програмер брише старе golden-фајлове и покреће тестове са flag record. Paparazzi поново креира све golden-фајлове. Затим програмер комитује нови golden заједно са променом кода. У прегледу кода, рецензент види diff старих и нових golden. Ако су промене одобрене — PR се спаја. Ако не — програмер исправља код и поново покреће тестове. Никад не ажурирајте golden аутоматски на CI — само локално.

SwiftSnapshotTesting и iOSSnapshotTestCase на iOS

SwiftSnapshotTesting — библиотека од pointfree.co, творци Composable Architecture. Подржава UIView, UIViewController, CALayer и SwiftUI View. Принцип: assertSnapshot(matching: view, as: .image). При првом покретању golden се креира аутоматски. При наредним — пореди се. Ако разлика премаши дозвољену — тест пада. SwiftSnapshotTesting ради преко UIGraphicsImageRenderer, који је компатибилан са 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 (бивши FBSnapshotTestCase) — библиотека од Uber за UIKit. За разлику од SwiftSnapshotTesting, iOSSnapshotTestCase захтева одређивање величине екрана и оријентације. Golden-фајлови — PNG у фолдеру ReferenceImages. Предност: ради са UIKit без SwiftUI и подржава iOS 12+. Недостатак: не ажурира golden аутоматски — мора се покренути са flag record. SwiftSnapshotTesting је модернији и препоручује се за нове пројекте.

Device-specific golden — golden-фајлови се разликују за различите величине екрана и оријентације. Стандардни приступ: именовати golden као TestName@3x~iPhone14.png. SwiftSnapshotTesting аутоматски додаје суфикс уређаја ако је дат параметар .image(on: .iPhoneSe). На Android Paparazzi користи DeviceConfig за подешавање величине. Чувајте golden за сваки подржани облик уређаја посебно. Немојте користити један golden за различите величине — то ће довести до flaky тестова.

Рад са golden-фајловима у CI и управљање ажурирањима

CI pipeline — golden-тестови треба да се покрећу при сваком Pull Request. Ако тест падне, CI приказује diff-слику као артефакт изградње. Програмер прегледа diff и доноси одлуку. Важно: golden-фајлови генерисани на CI се никад аутоматски не комитују. Само локално генерисање од стране програмера после намерне промене. GitHub Actions и GitLab CI подржавају учитавање артефакта (png, html) за преглед diff у прегледачу.

Величина репозиторијума — golden-фајлови брзо расту. 500 тестова = 100-400 MB PNG. Решења: (1) Git LFS — сваки golden се чува у LFS, клонира се само при checkout. (2) Чувати golden у одвојеном репозиторијуму и повезати као субмодул. (3) S3 + кеширање — golden на S3, CI преузима само измењене фајлове по контролном збиру. У IT Sectr користимо Git LFS са track *.png filter=lfs diff=lfs merge=lfs text=false. Локално golden леже у src/test/goldens/.

Преглед кода golden — обични git diff не показује промене PNG. Решења: (1) GitHub отвара PNG слике при клику. (2) Користити Review Apps, где је golden-diff видљив у прегледачу. (3) Генерисати HTML извештај са колонама пре/после/diff. Paparazzi креира HTML извештај са три колоне: actual, expected, diff. Извештај се прилаже CI артефактима. Рецензенти прегледају извештај без преузимања фајлова локално.

Када ажурирати golden — само после свесне промене UI. Промена фонта, боје, размака, иконе — golden треба ажурирати. Додавање новог дугмета, премештање елемената — golden треба ажурирати. Исправка грешке која мења изглед — golden треба ажурирати. Рефакторисање без промене UI — golden не треба ажурирати. Ако се golden мења без промене UI кода — то је flaky test узрокован окружењем, тражите узрок у CI агентима или верзијама зависности.

Често постављана питања

Чим се Golden Test разликује од Screenshot Test?

Golden Test — snapshot-тест на нивоу компоненте у unit-test окружењу (брз, без емулатора). Screenshot Test — снимање целог екрана на уређају или емулатору (спор, али реалистичан). Golden ради ван екрана, screenshot — са правим дисплејем. Golden је погодан за CI при сваком комиту, screenshot — за nightly пре издања.

Како се борити са flaky golden-тестовима?

Главни узроци: (1) Различити GPU на CI — користите исте CI агенте. (2) Различите верзије фонтова — фиксирајте верзију ОС. (3) Различити антиалиасинг — подесите threshold (Roborazzi, iOSSnapshotTestCase). (4) Анимације — искључите анимације у тестовима. (5) Системски елементи (статус-бар) — користите безоквирни device config. Paparazzi није подложан flakiness због Layoutlib.

Може ли се Golden Test користити са Jetpack Compose?

Да. Paparazzi има уграђену подршку за Compose преко paparazzi.snapshot { }. Roborazzi такође подржава Compose. На iOS SwiftSnapshotTesting ради са SwiftUI преко UIHostingController. Компоненте Compose се рендерују преко Layoutlib, SwiftUI — преко UIKit рендеровања. Ограничење: анимације Compose и SwiftUI нису подржане — golden-тест снима само почетно стање.

Како аутоматски прихватити измене golden?

Никад не аутоматизујте прихватање golden на CI. Само локално: програмер брише старе golden-фајлове из директоријума и покреће тестове са flag record (Paparazzi: record=true, SwiftSnapshotTesting: record=true). Golden-фајлови се поново креирају. Програмер прегледа сваки golden на исправност, комитује промене заједно са кодом. Аутоматско прихватање на CI ће довести до пропуштања грешака у UI.

Да ли Golden Test успорава изградњу?

Golden-тестови су бржи од инструменталних (UI Automator, XCUITest). Један golden-тест се извршава за 50-200 ms (Paparazzi: 100-150 ms на просечном MacBook Pro). 500 golden-тестова = 25-100 секунди. Упоредите са screenshot-тестовима преко емулатора: 5-30 секунди по тесту. Golden-тестови не успоравају изградњу: 100 тестова = ~15 секунди, што је прихватљиво за pre-merge проверу.

Закључак

  • Golden Test — визуелно тестирање UI компоненти поређењем са еталонском PNG сликом
  • Процес — рендер компоненте ван екрана, поређење пиксел по пиксел, diff при несовпадању
  • Android — Paparazzi (Compose/View, Layoutlib) и Roborazzi (Compose/View, threshold, Robolectric)
  • iOS — SwiftSnapshotTesting (pointfree) и iOSSnapshotTestCase од Uber за UIKit и SwiftUI
  • CI Pipeline — golden-тестови на сваком PR, diff артефакти, само локално ажурирање golden
  • Git LFS — обавезан за чување PNG фајлова (100-400 MB за 500 тестова)
  • Flakiness — повезан са GPU, фонтовима и антиалиасингом; решава се threshold и истим CI агентима

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође