Golden Test (snapshot-test, etalon testi) — UI-nin vizual test metodu olub, komponentin cari renderinin əvvəlcədən saxlanmış etalon şəkli (golden-fayl) ilə müqayisə edildiyi üsuldur. Piksel dəyişiklikləri müəyyən edilmiş həddi aşarsa, test uğursuz olur və diff şəkli yaradır. Tərtibatçı diff-ə baxır və ya dəyişiklikləri qəbul edir (golden-i yeniləyir), ya da səhvi düzəldir. Ətraflı Meta Engineering-in Paparazzi haqqında məqaləsində.
Əsas məqamlar
Golden Test — komponentin görünüşünün etalonla piksel-piksel müqayisəsi yolu ilə avtomatlaşdırılmış yoxlamadır. Proses: (1) tərtibatçı və ya testçi komponentin ilk şəklini çəkir — bu “golden” (etalon) olur. (2) Golden faylı testin yanında depozitariyada saxlanılır. (3) Növbəti icralarda test komponenti yenidən render edir və saxlanmış golden ilə müqayisə edir. (4) Şəkillər uyğun gəlirsə — test yaşıl olur. Fərqlənirsə — test diff ilə qırmızı olur. Qərar: ya dəyişikliklər gözlənilir (golden yenilənir), ya da bu səhvdir.
Golden necə yaradılır — kitabxana komponenti real ekran olmadan off-screen buferdə render edir (Android: Canvas, iOS: UIGraphicsImageRenderer). Bu o deməkdir ki, golden-testlər CI-da virtual displey olmadan işləyir, bu da icranı sürətləndirir. Paparazzi Android-də Layoutlib (Android Studio-nun Layout Editor ilə eyni mühərrik) istifadə edir. iOSSnapshotTestCase UIKit renderini CGImage-ə çevirir. Nəticə — sabit ölçülü PNG faylı.
Golden faylları — bir ekranın PNG şəkli (1080x1920) mürəkkəblikdən asılı olaraq 200-800 KB yer tutur. 500 golden-testi olan layihə üçün bu ~100-400 MB depozitariyadır. Həll yolları: (1) golden-i Git LFS-də saxlamaq. (2) PNG sıxılmasından istifadə (pngcrush, oxipng). (3) Golden-i ayrıca anbarda (S3) saxlamaq və qurarkən çəkmək. IT Sectr-də golden-i hər fayl üçün 1 MB həddi ilə Git LFS-də saxlayırıq — bu testlərin 90% üçün kifayətdir.
Flaky golden testlər — golden-testlərin əsas problemi. Müxtəlif GPU, şrift versiyaları və anti-aliasing piksellərdə mikro-fərqlər verir. Həll yolları: threshold (fərqli piksellərin icazə verilən faizi), fuzzy comparison (bulanık müqayisə) və eyni CI agentlərində işə salmaq (eyni GPU, OS, emulator versiyası). Paparazzi-də pixel-perfect müqayisə istifadə olunur, ona görə də CI agentləri eyni olmalıdır.
Golden Test — sabit etalon ilə screenshot-testin bir növüdür. “Golden” termini etalonun komanda tərəfindən təsdiqləndiyini və depozitariyada saxlandığını bildirir. Şəklin hər hansı dəyişməsi tərtibatçının şüurlu qərarını tələb edir: golden-i yeniləmək və ya kodu düzəltmək. Golden Test ayrı-ayrı komponentlər səviyyəsində işləyir (Composable, UIView) və real cihaz tələb etmir.
Screenshot Test — daha geniş anlayış. Screenshot-test real məlumatlar, naviqasiya, sistem status çubuğu və animasiyalarla bütün ekranı çəkə bilər. Screenshot-testlər çox vaxt real cihazlarda və ya emulatorlarda UI Automator (Android) və ya XCUITest (iOS) vasitəsilə işə salınır. Golden-testlər emulatorsız unit-test mühitində (JVM, XCTest) işləyir və yalnız tək komponenti çəkir.
| Xarakteristika | Golden Test | Screenshot Test |
|---|---|---|
| Səviyyə | Komponent/Composable/View | Bütün ekran |
| Mühit | Unit-test (off-screen bufer) | Cihaz/Emulator |
| Sürət | 50-200 ms test başına | 2-30 saniyə test başına |
| Animasiyalar | Dəstəklənmir | Dəstəklənir (fasilələrlə) |
| CI GPU-suz | İşləyir (Layoutlib) | Emulator tələb edir |
| Quraşdırma çətinliyi | Aşağı | Yüksək (Emulator/Device Farm) |
| Flakiness | Orta (müxtəlif GPU) | Yüksək (emulator, vaxt) |
Golden vs Screenshot — hər commit-də ayrı-ayrı UI komponentlərini (düymə, kart, dialoq) yoxlamaq üçün golden-testlər. Screenshot-testlər — buraxılışdan əvvəl bütün ekranların E2E yoxlanması üçün. Golden-testlər tərtibatçıya sürətli geribildirim verir, screenshot-testlər — bütün tətbiqin bütövlüyünə inam. IT Sectr-də Pull Request üçün golden-testlərdən (3-5 dəqiqə), nightly üçün isə screenshot-testlərdən (30-60 dəqiqə) istifadə edirik.
Paparazzi — Cash App (Square) kitabxanası olub, Android View və Jetpack Compose komponentlərini emulatorsız PNG-ə render edir. Layoutlib (Android Studio Preview ilə eyni mühərrik) istifadə edir. Quraşdırma: Gradle plaqini qoşmaq, @Test və @RunWith(PaparazziRule::class) ilə test yazmaq, paparazzi.snapshot(view) çağırmaq. Paparazzi animasiyaları, videonu və Real Device-i dəstəkləmir — yalnız statik render.
// build.gradle.kts (module)
plugins {
id("app.cash.paparazzi") version "1.3.1"
}
// Compose komponenti üçün Golden test
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 — Compose, View və şəkil müqayisəsini dəstəkləyən Paparazzi alternativi. Fərq: Roborazzi Robolectric vasitəsilə işləyir və threshold (icazə verilən piksel fərqi faizi) dəstəkləyir. Bu, CI-da müxtəlif GPU-larla flakiness-i azaldır. Roborazzi həmçinin dəyişikliklərin GIF animasiyasını (əvvəl/sonra/diff) yarada bilir, bu kod baxışı üçün əlverişlidir. Golden fayllarının formatı: PNG + JSON metadatası.
Golden yeniləmə — UI-nin məqsədli dəyişikliyindən sonra tərtibatçı köhnə golden fayllarını silir və testləri record flag ilə işə salır. Paparazzi bütün golden fayllarını yenidən yaradır. Sonra tərtibatçı kodu ilə birlikdə yeni golden-i commit edir. Kod baxışında rəyçi köhnə və yeni golden-lərin diff-ni görür. Dəyişikliklər təsdiqlənərsə — PR birləşdirilir. Yoxsa — tərtibatçı kodu düzəldir və testləri yenidən işə salır. Heç vaxt golden-i CI-da avtomatik yeniləməyin — yalnız lokalda.
SwiftSnapshotTesting — pointfree.co kitabxanası, Composable Architecture yaradıcıları. UIView, UIViewController, CALayer və SwiftUI View dəstəkləyir. Prinsip: assertSnapshot(matching: view, as: .image). İlk işə salmada golden avtomatik yaradılır. Sonrakılarda — müqayisə edilir. Fərq icazə veriləni aşarsa — test uğursuz olur. SwiftSnapshotTesting CI ilə uyğun olan UIGraphicsImageRenderer vasitəsilə işləyir (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 (keçmiş FBSnapshotTestCase) — Uber-dən UIKit üçün kitabxana. SwiftSnapshotTesting-dən fərqli olaraq, iOSSnapshotTestCase ekran ölçüsü və oriyentasiyanın təyin edilməsini tələb edir. Golden fayllar — ReferenceImages qovluğunda PNG. Üstünlük: SwiftUI olmadan UIKit ilə işləyir və iOS 12+ dəstəkləyir. Çatışmazlıq: golden-i avtomatik yeniləmir — record flag ilə işə salmaq lazımdır. SwiftSnapshotTesting daha müasirdir və yeni layihələr üçün tövsiyə olunur.
Cihaza özəl golden — golden faylları müxtəlif ekran ölçüləri və oriyentasiyalar üçün fərqlənir. Standart yanaşma: golden-i TestName@3x~iPhone14.png olaraq adlandırmaq. SwiftSnapshotTesting .image(on: .iPhoneSe) parametri verildikdə avtomatik cihaz suffiksi əlavə edir. Android-də Paparazzi ölçü təyini üçün DeviceConfig istifadə edir. Hər dəstəklənən cihaz form faktoru üçün golden-i ayrı saxlayın. Müxtəlif ölçülər üçün bir golden istifadə etməyin — bu flaky testlərə gətirib çıxarır.
CI pipeline — golden-testlər hər Pull Request-də işə salınmalıdır. Test uğursuz olarsa, CI diff şəklini qurma artefaktı kimi göstərir. Tərtibatçı diff-ə baxır və qərar verir. Əhəmiyyətli: CI-da yaradılmış golden faylları heç vaxt avtomatik commit edilmir. Yalnız tərtibatçı tərəfindən məqsədli dəyişiklikdən sonra lokal yaradılma. GitHub Actions və GitLab CI brauzerdə diff-ə baxmaq üçün artefaktların (png, html) yüklənməsini dəstəkləyir.
Depozitariyanın ölçüsü — golden faylları sürətlə böyüyür. 500 test = 100-400 MB PNG. Həll yolları: (1) Git LFS — hər golden LFS-də saxlanılır, yalnız checkout-da klonlanır. (2) Golden-i ayrı depozitariyada saxlamaq və altmodul kimi qoşmaq. (3) S3 + keşləmə — golden S3-də, CI yalnız yoxlama məbləği ilə dəyişdirilmiş faylları yükləyir. IT Sectr-də track *.png filter=lfs diff=lfs merge=lfs text=false ilə Git LFS istifadə edirik. Lokalda golden-lər src/test/goldens/ qovluğunda yerləşir.
Golden-ə kod baxışı — adi git diff PNG dəyişikliklərini göstərmir. Həll yolları: (1) GitHub PNG şəkillərini klikdə açır. (2) Golden-diff-in brauzerdə göründüyü Review Apps-dən istifadə. (3) Əvvəl/sonra/diff sütunları ilə HTML hesabatı yaratmaq. Paparazzi üç sütunlu HTML hesabatı yaradır: actual, expected, diff. Hesabat CI artefaktlarına əlavə olunur. Rəyçilər faylları lokalda endirmədən hesabata baxırlar.
Golden nə vaxt yenilənməlidir — yalnız UI-nin şüurlu dəyişikliyindən sonra. Şrift, rəng, boşluq, işarənin dəyişməsi — golden yenilənməlidir. Yeni düymənin əlavə edilməsi, elementlərin yerdəyişməsi — golden yenilənməlidir. Görünüşü dəyişən səhv düzəlişi — golden yenilənməlidir. UI dəyişmədən refaktorinq — golden yenilənməməlidir. Golden UI kodu dəyişmədən dəyişirsə — bu mühit səbəbindən flaky testdir, səbəbi CI agentlərində və ya asılılıq versiyalarında axtarın.
Tez-tez verilən suallar
Golden Test — unit-test mühitində komponent səviyyəsində snapshot-test (sürətli, emulatorsuz). Screenshot Test — cihazda və ya emulatorda bütün ekranın çəkilişi (yavaş, lakin realistik). Golden off-screen buferlə işləyir, screenshot — real displeylə. Golden hər commit-də CI üçün uyğundur, screenshot — buraxılışdan əvvəl nightly üçün.
Əsas səbəblər: (1) CI-da müxtəlif GPU — eyni CI agentlərindən istifadə edin. (2) Müxtəlif şrift versiyaları — OS versiyasını fiksasiya edin. (3) Müxtəlif anti-aliasing — threshold-u qurun (Roborazzi, iOSSnapshotTestCase). (4) Animasiyalar — testlərdə animasiyaları söndürün. (5) Sistem elementləri (status çubuğu) — çərçivəsiz device config istifadə edin. Paparazzi Layoutlib sayəsində flakiness-ə məruz qalmır.
Bəli. Paparazzi paparazzi.snapshot { } vasitəsilə Compose dəstəyinə malikdir. Roborazzi də Compose dəstəkləyir. iOS-da SwiftSnapshotTesting UIHostingController vasitəsilə SwiftUI ilə işləyir. Compose komponentləri Layoutlib vasitəsilə, SwiftUI — UIKit renderi ilə göstərilir. Məhdudiyyət: Compose və SwiftUI animasiyaları dəstəklənmir — golden-test yalnız ilkin vəziyyəti çəkir.
Heç vaxt CI-da golden qəbulunu avtomatlaşdırmayın. Yalnız lokalda: tərtibatçı kataloqdan köhnə golden fayllarını silir və testləri record flag ilə işə salır (Paparazzi: record=true, SwiftSnapshotTesting: record=true). Golden faylları yenidən yaradılır. Tərtibatçı hər golden-i düzgünlük baxımından yoxlayır, kodu ilə birlikdə dəyişiklikləri commit edir. CI-da avtomatik qəbul UI səhvlərinin qaçırılmasına gətirib çıxaracaq.
Golden-testlər instrumental testlərdən (UI Automator, XCUITest) daha sürətlidir. Bir golden-test 50-200 ms-ə icra olunur (Paparazzi: orta MacBook Pro-da 100-150 ms). 500 golden-test = 25-100 saniyə. Emulator vasitəsilə screenshot-testlərlə müqayisə edin: test başına 5-30 saniyə. Golden-testlər qurmanı yavaşlatmır: 100 test = ~15 saniyə, bu pre-merge yoxlaması üçün məqbuldur.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun