Golden Test (snapshot-test, referenciatesztelés) — a UI vizuális tesztelésének módszere, amelyben a komponens aktuális renderelése egy előre elmentett referenciaképhez (golden-fájl) hasonlít. Ha a pixelváltozások meghaladják a beállított küszöbértéket, a teszt sikertelen lesz és diff-képet generál. A fejlesztő megtekinti a diff-et és vagy elfogadja a változtatásokat (frissíti a golden-t), vagy kijavítja a hibát. Bővebben a Meta Engineering cikkében a Paparazziról.
Főbb pontok
Golden Test — a komponens megjelenésének automatizált ellenőrzése pixelről-pixelre történő összehasonlítással a referenciával. Folyamat: (1) a fejlesztő vagy tesztelő elkészíti a komponens első felvételét — ez a “golden” (referencia). (2) A golden-fájl a teszt mellett a repository-ban kerül elmentésre. (3) A későbbi futtatások során a teszt újra rendereli a komponenst és összehasonlítja az elmentett golden-nel. (4) Ha a képek egyeznek — a teszt zöld. Ha eltérnek — a teszt piros diff-fel. Döntés: vagy a változtatások várhatóak (frissítjük a golden-t), vagy ez egy hiba.
Hogyan generálódik a golden — a könyvtár a komponenst egy off-screen pufferben rendereli (Android: Canvas, iOS: UIGraphicsImageRenderer) valódi kijelző nélkül. Ez azt jelenti, hogy a golden-tesztek CI-n működnek képernyő-emulátor (virtual display) nélkül, ami felgyorsítja a végrehajtást. A Paparazzi Androidon az Android Studio Layoutlib-jét használja — ugyanazt a motort, mint a Layout Editor. Az iOSSnapshotTestCase UIKit-renderelést használ CGImage-be. Eredmény — egy rögzített méretű PNG fájl.
Golden-fájlok — egy képernyő PNG felvétele (1080x1920) 200-800 KB-ot foglal a komplexitástól függően. Egy 500 golden-teszttel rendelkező projekt esetén ez ~100-400 MB a repository-ban. Megoldások: (1) golden tárolása Git LFS-ben. (2) PNG tömörítés használata (pngcrush, oxipng). (3) Golden tárolása külön tárhelyen (S3) és letöltés build-kor. Az IT Sectr-nél golden-t Git LFS-ben tárolunk 1 MB fájlonkénti küszöbértékkel — ez a tesztek 90%-ához elegendő.
Flaky golden tesztek — a golden-tesztek fő problémája. Különböző GPU-k, betűtípus-verziók és anti-aliasing mikro-eltéréseket okoznak a pixelekben. Megoldások: threshold (eltérő pixelek megengedett százaléka), fuzzy comparison (elmosódott összehasonlítás) és azonos CI-ügynökökön történő futtatás (azonos GPU, OS, emulátorverzió). A Paparazzi pixel-perfect összehasonlítást használ, ezért a CI-ügynököknek azonosnak kell lenniük.
Golden Test — a screenshot-tesztelés egy fajtája rögzített referenciával. A “golden” kifejezés azt jelenti, hogy a referenciát a csapat jóváhagyta (elfogadta) és a repository-ban tárolja. A kép bármilyen változása a fejlesztő tudatos döntését igényli: a golden frissítése vagy a kód javítása. A Golden Test egyes komponensek szintjén működik (Composable, UIView) és nem igényel valódi eszközt.
Screenshot Test — tágabb fogalom. A Screenshot-test a teljes képernyőt rögzítheti valódi adatokkal, navigációval, rendszer állapotsorral és animációkkal. A Screenshot-tesztek gyakran valódi eszközökön vagy emulátorokon futnak UI Automator (Android) vagy XCUITest (iOS) segítségével. A Golden-tesztek unit-test környezetben (JVM, XCTest) működnek emulátor nélkül és csak egy komponenst rögzítenek.
| Jellemző | Golden Test | Screenshot Test |
|---|---|---|
| Szint | Komponens/Composable/View | Teljes képernyő |
| Környezet | Unit-test (off-screen puffer) | Eszköz/Emulátor |
| Sebesség | 50-200 ms tesztenként | 2-30 másodperc tesztenként |
| Animációk | Nem támogatottak | Támogatottak (szünetekkel) |
| CI GPU nélkül | Működik (Layoutlib) | Emulátort igényel |
| Beállítás bonyolultsága | Alacsony | Magas (Emulátor/Device Farm) |
| Flakiness | Közepes (különböző GPU) | Magas (emulátor, idő) |
Golden vs Screenshot — golden-tesztek az egyes UI-komponensek (gomb, kártya, párbeszédablak) ellenőrzésére minden commit-nál. Screenshot-tesztek — a teljes képernyők E2E ellenőrzésére kiadás előtt. A golden-tesztek gyors visszajelzést adnak a fejlesztőnek, a screenshot-tesztek — bizalmat a teljes alkalmazás integritásában. Az IT Sectr-nél golden-teszteket használunk Pull Request-hez (3-5 perc), screenshot-teszteket — nightly futtatásokhoz (30-60 perc).
Paparazzi — a Cash App (Square) könyvtára, amely Android View és Jetpack Compose komponenseket renderel PNG-be emulátor nélkül. A Layoutlib-et használja (ugyanaz a motor, mint az Android Studio Preview). Beállítás: Gradle plugin csatlakoztatása, teszt írása @Test és @RunWith(PaparazziRule::class) paranccsal, paparazzi.snapshot(view) meghívása. A Paparazzi nem támogatja az animációkat, videót és Real Device-t — csak statikus komponens-renderelést.
// build.gradle.kts (module)
plugins {
id("app.cash.paparazzi") version "1.3.1"
}
// Golden test a Compose-komponenshez
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 — a Paparazzi alternatívája Compose, View és képek összehasonlításának támogatásával. Különbség: a Roborazzi Robolectric-en keresztül működik és támogatja a threshold-t (megengedett pixelkülönbség százaléka). Ez csökkenti a flakiness-t különböző GPU-k esetén CI-n. A Roborazzi képes GIF-animációkat is készíteni a változásokról (előtte/utána/diff), ami kényelmes a kód áttekintéséhez. A golden-fájlok formátuma: PNG + JSON metaadatok.
Golden frissítése — a UI szándékos megváltoztatása után a fejlesztő törli a régi golden-fájlokat és record flag-gel futtatja a teszteket. A Paparazzi újra létrehozza az összes golden-fájlt. Ezután a fejlesztő commit-eli az új golden-t a kódváltoztatással együtt. A kód áttekintése során a bíráló látja a régi és új golden-ek diff-jét. Ha a változtatások jóvá vannak hagyva — a PR egyesítésre kerül. Ha nem — a fejlesztő kijavítja a kódot és újra futtatja a teszteket. Soha ne frissítse a golden-t automatikusan CI-n — csak lokálisan.
SwiftSnapshotTesting — a pointfree.co könyvtára, a Composable Architecture alkotói. Támogatja a UIView, UIViewController, CALayer és SwiftUI View típusokat. Elv: assertSnapshot(matching: view, as: .image). Az első futtatáskor a golden automatikusan létrejön. A következőknél — összehasonlításra kerül. Ha a különbség meghaladja a megengedettet — a teszt sikertelen. A SwiftSnapshotTesting a UIGraphicsImageRenderer-en keresztül működik, amely kompatibilis a CI-vel (Xcode Cloud, GitHub Actions).
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 (korábban FBSnapshotTestCase) — az Uber könyvtára UIKit számára. A SwiftSnapshotTesting-től eltérően az iOSSnapshotTestCase megköveteli a képernyő méretének és tájolásának megadását. Golden-fájlok — PNG a ReferenceImages mappában. Előny: UIKit-kel működik SwiftUI nélkül és támogatja az iOS 12+-t. Hátrány: nem frissíti automatikusan a golden-t — record flag-gel kell futtatni. A SwiftSnapshotTesting modernebb és új projektekhez ajánlott.
Eszközspecifikus golden — a golden-fájlok eltérőek a különböző képernyőméretek és tájolások esetén. Szabványos megközelítés: a golden elnevezése TestName@3x~iPhone14.png formátumban. A SwiftSnapshotTesting automatikusan hozzáadja az eszköz utótagot, ha az .image(on: .iPhoneSe) paraméter meg van adva. Androidon a Paparazzi a DeviceConfig-ot használja a méret beállításához. Tárolja a golden-t minden támogatott eszköz form faktorhoz külön. Ne használjon egy golden-t különböző méretekhez — ez flaky tesztekhez vezet.
CI pipeline — a golden-teszteket minden Pull Request-nél futtatni kell. Ha a teszt sikertelen, a CI megjeleníti a diff-képet build műtermékként. A fejlesztő megtekinti a diff-et és döntést hoz. Fontos: a CI-n generált golden-fájlok soha nem kerülnek automatikus commit-ra. Csak a fejlesztő általi lokális generálás szándékos változtatás után. A GitHub Actions és a GitLab CI támogatja a műtermékek (png, html) feltöltését a diff böngészőben történő megtekintéséhez.
Repository mérete — a golden-fájlok gyorsan nőnek. 500 teszt = 100-400 MB PNG. Megoldások: (1) Git LFS — minden golden LFS-ben tárolva, csak checkout-kor klónozva. (2) Golden tárolása külön repository-ban és almodulként csatlakoztatva. (3) S3 + gyorsítótárazás — golden az S3-on, a CI csak a checksum alapján módosított fájlokat tölti le. Az IT Sectr-nél Git LFS-t használunk track *.png filter=lfs diff=lfs merge=lfs text=false beállítással. Lokálisan a golden-ek a src/test/goldens/ mappában találhatók.
Golden kód áttekintése — a szokásos git diff nem mutatja a PNG-változásokat. Megoldások: (1) A GitHub megnyitja a PNG-képeket kattintásra. (2) Review Apps használata, ahol a golden-diff látható a böngészőben. (3) HTML-jelentés generálása előtte/utána/diff oszlopokkal. A Paparazzi három oszlopos HTML-jelentést készít: actual, expected, diff. A jelentés a CI-műtermékekhez csatolódik. A bírálók a jelentést a fájlok lokális letöltése nélkül tekintik meg.
Mikor frissítsük a golden-t — csak a UI tudatos megváltoztatása után. Betűtípus, szín, térköz, ikon változása — a golden-t frissíteni kell. Új gomb hozzáadása, elemek átrendezése — a golden-t frissíteni kell. Hibajavítás, amely megváltoztatja a megjelenést — a golden-t frissíteni kell. Refaktorálás UI-változtatás nélkül — a golden-t nem kell frissíteni. Ha a golden UI-kód változtatása nélkül változik — ez egy flaky teszt, amelyet a környezet okoz, keresse az okot a CI-ügynökökben vagy a függőségi verziókban.
Gyakran ismételt kérdések
Golden Test — snapshot-test komponens szinten unit-test környezetben (gyors, emulátor nélkül). Screenshot Test — a teljes képernyő rögzítése eszközön vagy emulátoron (lassú, de valósághű). A golden off-screen pufferrel működik, a screenshot — valódi kijelzővel. A golden minden commit-nál CI-re alkalmas, a screenshot — nightly futtatásokra kiadás előtt.
Fő okok: (1) Különböző GPU-k CI-n — használjon azonos CI-ügynököket. (2) Különböző betűtípus-verziók — rögzítse az OS verzióját. (3) Különböző anti-aliasing — állítsa be a threshold-t (Roborazzi, iOSSnapshotTestCase). (4) Animációk — kapcsolja ki az animációkat a tesztekben. (5) Rendszerelemek (állapotsor) — használjon keret nélküli device config-ot. A Paparazzi nem érzékeny a flakiness-re a Layoutlib miatt.
Igen. A Paparazzi beépített támogatással rendelkezik a Compose-hoz a paparazzi.snapshot { } segítségével. A Roborazzi szintén támogatja a Compose-t. iOS-en a SwiftSnapshotTesting a SwiftUI-val működik a UIHostingController-en keresztül. A Compose-komponensek a Layoutlib-en keresztül, a SwiftUI — UIKit-rendereléssel jelenik meg. Korlátozás: a Compose és SwiftUI animációk nem támogatottak — a golden-test csak a kezdeti állapotot rögzíti.
Soha ne automatizálja a golden elfogadását CI-n. Csak lokálisan: a fejlesztő törli a régi golden-fájlokat a könyvtárból és record flag-gel futtatja a teszteket (Paparazzi: record=true, SwiftSnapshotTesting: record=true). A golden-fájlok újra létrejönnek. A fejlesztő ellenőrzi minden golden helyességét, commit-eli a változtatásokat a kóddal együtt. Az automatikus elfogadás CI-n UI-hibák kihagyásához vezet.
A golden-tesztek gyorsabbak, mint az instrumentális tesztek (UI Automator, XCUITest). Egy golden-test 50-200 ms alatt fut le (Paparazzi: 100-150 ms egy átlagos MacBook Pro-n). 500 golden-test = 25-100 másodperc. Hasonlítsa össze az emulátoros screenshot-tesztekkel: 5-30 másodperc tesztenként. A golden-tesztek nem lassítják a build-et: 100 teszt = ~15 másodperc, ami elfogadható a pre-merge ellenőrzéshez.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is