Golden Test (snapshot-test, etalon testi) — UI vizual testlash usuli bo'lib, komponentning joriy renderi oldindan saqlangan etalon tasvir (golden-fayl) bilan solishtiriladi. Agar piksel o'zgarishlari belgilangan chegaradan oshsa, test muvaffaqiyatsiz bo'ladi va diff tasvirini yaratadi. Dasturchi diff-ni ko'rib chiqadi va yo o'zgarishlarni qabul qiladi (golden-ni yangilaydi) yoki xatoni tuzatadi. Batafsil Meta Engineering-ning Paparazzi haqidagi maqolasida.
Asosiy fikrlar
Golden Test — komponent ko'rinishini etalon bilan pikselma-piksel solishtirish orqali avtomatlashtirilgan tekshirish. Jarayon: (1) dasturchi yoki tester komponentning birinchi suratini oladi — bu “golden” (etalon). (2) Golden fayli test yonida repozitariyda saqlanadi. (3) Keyingi ishga tushirishlarda test komponentni qayta renderlaydi va saqlangan golden bilan solishtiradi. (4) Tasvirlar mos kelsa — test yashil. Farq qilsa — test diff bilan qizil. Qaror: yo o'zgarishlar kutilgan (golden-ni yangilaymiz) yoki bu xato.
Golden qanday yaratiladi — kutubxona komponentni haqiqiy displeysiz off-screen buferda renderlaydi (Android: Canvas, iOS: UIGraphicsImageRenderer). Bu golden-testlar CI-da virtual displeysiz ishlashini anglatadi, bu esa bajarishni tezlashtiradi. Paparazzi Android-da Layoutlib (Android Studio ning Layout Editor bilan bir xil dvigatel) dan foydalanadi. iOSSnapshotTestCase UIKit renderini CGImage-ga aylantiradi. Natija — qat'iy o'lchamdagi PNG fayli.
Golden fayllari — bir ekranning PNG surati (1080x1920) murakkablikka qarab 200-800 KB egallaydi. 500 golden-testli loyiha uchun bu ~100-400 MB repozitariyda. Yechimlar: (1) golden-ni Git LFS-da saqlash. (2) PNG siqishdan foydalanish (pngcrush, oxipng). (3) Golden-ni alohida omborda (S3) saqlash va qurishda yuklab olish. IT Sectr-da golden-ni har bir fayl uchun 1 MB chegarasi bilan Git LFS-da saqlaymiz — bu testlarning 90% uchun yetarli.
Flaky golden testlar — golden-testlarning asosiy muammosi. Turli GPU, shrift versiyalari va anti-aliasing piksellarda mikro-farqlar beradi. Yechimlar: threshold (farqli piksellarning ruxsat etilgan foizi), fuzzy comparison (xira solishtirish) va bir xil CI agentlarida ishga tushirish (bir xil GPU, OS, emulator versiyasi). Paparazzi-da pixel-perfect solishtirish qo'llaniladi, shuning uchun CI agentlari bir xil bo'lishi kerak.
Golden Test — qat'iy etalon bilan screenshot-testning bir turi. “Golden” atamasi etalon jamoa tomonidan tasdiqlangan va repozitariyda saqlanganligini bildiradi. Tasvirning har qanday o'zgarishi dasturchining ongli qarorini talab qiladi: golden-ni yangilash yoki kodni tuzatish. Golden Test alohida komponentlar darajasida ishlaydi (Composable, UIView) va haqiqiy qurilma talab qilmaydi.
Screenshot Test — kengroq tushuncha. Screenshot-test haqiqiy ma'lumotlar, navigatsiya, tizim holat paneli va animatsiyalar bilan butun ekranni olishi mumkin. Screenshot-testlar ko'pincha haqiqiy qurilmalarda yoki emulatorlarda UI Automator (Android) yoki XCUITest (iOS) orqali ishga tushiriladi. Golden-testlar emulatorsiz unit-test muhitida (JVM, XCTest) ishlaydi va faqat bitta komponentni oladi.
| Xususiyat | Golden Test | Screenshot Test |
|---|---|---|
| Daraja | Komponent/Composable/View | Butun ekran |
| Muhit | Unit-test (off-screen bufer) | Qurilma/Emulator |
| Tezlik | 50-200 ms test boshiga | 2-30 soniya test boshiga |
| Animatsiyalar | Qo'llab-quvvatlanmaydi | Qo'llab-quvvatlanadi (pauzalar bilan) |
| CI GPU-siz | Ishlaydi (Layoutlib) | Emulator talab qiladi |
| Sozlash murakkabligi | Past | Yuqori (Emulator/Device Farm) |
| Flakiness | O'rta (turli GPU) | Yuqori (emulator, vaqt) |
Golden vs Screenshot — har bir commitda alohida UI komponentlarini (tugma, karta, dialog) tekshirish uchun golden-testlar. Screenshot-testlar — chiqarishdan oldin butun ekranlarning E2E tekshiruvi uchun. Golden-testlar dasturchiga tez qayta aloqa beradi, screenshot-testlar — butun ilovaning yaxlitligiga ishonch. IT Sectr-da Pull Request uchun golden-testlardan (3-5 daqiqa), nightly uchun esa screenshot-testlardan (30-60 daqiqa) foydalanamiz.
Paparazzi — Cash App (Square) kutubxonasi bo'lib, Android View va Jetpack Compose komponentlarini emulatorsiz PNG-ga renderlaydi. Layoutlib (Android Studio Preview bilan bir xil dvigatel) dan foydalanadi. Sozlash: Gradle plaginini ulash, @Test va @RunWith(PaparazziRule::class) bilan test yozish, paparazzi.snapshot(view) chaqirish. Paparazzi animatsiyalar, video va Real Device-ni qo'llab-quvvatlamaydi — faqat statik render.
// build.gradle.kts (module)
plugins {
id("app.cash.paparazzi") version "1.3.1"
}
// Compose komponenti uchun 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 va tasvir solishtirishni qo'llab-quvvatlovchi Paparazzi alternativi. Farq: Roborazzi Robolectric orqali ishlaydi va threshold (ruxsat etilgan piksel farqi foizi) ni qo'llab-quvvatlaydi. Bu CI-da turli GPU bilan flakiness-ni kamaytiradi. Roborazzi shuningdek o'zgarishlarning GIF animatsiyasini (oldin/keyin/diff) yarata oladi, bu kod ko'rib chiqish uchun qulay. Golden fayllar formati: PNG + JSON metama'lumotlar.
Golden yangilash — UI-ning maqsadli o'zgarishidan so'ng dasturchi eski golden fayllarini o'chiradi va testlarni record bayrog'i bilan ishga tushiradi. Paparazzi barcha golden fayllarini qayta yaratadi. Keyin dasturchi kod o'zgarishi bilan birga yangi golden-ni commit qiladi. Kod ko'rib chiqishda sharhlovchi eski va yangi golden-larning diff-ni ko'radi. O'zgarishlar tasdiqlansa — PR birlashtiriladi. Aks holda — dasturchi kodni tuzatadi va testlarni qayta ishga tushiradi. Hech qachon golden-ni CI-da avtomatik yangilamang — faqat lokalda.
SwiftSnapshotTesting — pointfree.co kutubxonasi, Composable Architecture yaratuvchilari. UIView, UIViewController, CALayer va SwiftUI View-ni qo'llab-quvvatlaydi. Prinsip: assertSnapshot(matching: view, as: .image). Birinchi ishga tushirishda golden avtomatik yaratiladi. Keyingilarida — solishtiriladi. Agar farq ruxsat etilganidan oshsa — test muvaffaqiyatsiz bo'ladi. SwiftSnapshotTesting CI bilan mos keladigan UIGraphicsImageRenderer orqali ishlaydi (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 (sobiq FBSnapshotTestCase) — Uber-dan UIKit uchun kutubxona. SwiftSnapshotTesting-dan farqli o'laroq, iOSSnapshotTestCase ekran o'lchami va orientatsiyani belgilashni talab qiladi. Golden fayllar — ReferenceImages papkasida PNG. Afzallik: SwiftUI-siz UIKit bilan ishlaydi va iOS 12+ qo'llab-quvvatlaydi. Kamchilik: golden-ni avtomatik yangilamaydi — record bayrog'i bilan ishga tushirish kerak. SwiftSnapshotTesting zamonaviyroq va yangi loyihalar uchun tavsiya etiladi.
Qurilmaga xos golden — golden fayllari turli ekran o'lchamlari va orientatsiyalar uchun farqlanadi. Standart yondashuv: golden-ni TestName@3x~iPhone14.png deb nomlash. SwiftSnapshotTesting .image(on: .iPhoneSe) parametri berilganda avtomatik qurilma suffiksini qo'shadi. Android-da Paparazzi o'lcham sozlash uchun DeviceConfig dan foydalanadi. Har bir qo'llab-quvvatlanadigan qurilma form faktori uchun golden-ni alohida saqlang. Turli o'lchamlar uchun bitta golden ishlatmang — bu flaky testlarga olib keladi.
CI pipeline — golden-testlar har bir Pull Request-da ishga tushirilishi kerak. Agar test muvaffaqiyatsiz bo'lsa, CI diff tasvirini qurish artefakti sifatida ko'rsatadi. Dasturchi diff-ni ko'rib chiqadi va qaror qabul qiladi. Muhim: CI-da yaratilgan golden fayllari hech qachon avtomatik commit qilinmaydi. Faqat dasturchi tomonidan maqsadli o'zgarishdan so'ng lokal yaratish. GitHub Actions va GitLab CI brauzerda diff-ni ko'rish uchun artefaktlarni (png, html) yuklashni qo'llab-quvvatlaydi.
Repozitariy hajmi — golden fayllari tez o'sadi. 500 test = 100-400 MB PNG. Yechimlar: (1) Git LFS — har bir golden LFS-da saqlanadi, faqat checkout-da klonlanadi. (2) Golden-ni alohida repozitariyda saqlash va submodul sifatida ulash. (3) S3 + kesh — golden S3-da, CI faqat tekshirish summasi bo'yicha o'zgartirilgan fayllarni yuklaydi. IT Sectr-da track *.png filter=lfs diff=lfs merge=lfs text=false bilan Git LFS dan foydalanamiz. Lokalda golden-lar src/test/goldens/ papkasida joylashgan.
Golden kod ko'rib chiqish — oddiy git diff PNG o'zgarishlarini ko'rsatmaydi. Yechimlar: (1) GitHub PNG tasvirlarni bosganda ochadi. (2) Golden-diff brauzerda ko'rinadigan Review Apps dan foydalanish. (3) Oldin/keyin/diff ustunlari bilan HTML hisobot yaratish. Paparazzi uch ustunli HTML hisobot yaratadi: actual, expected, diff. Hisobot CI artefaktlariga biriktiriladi. Sharhlovchilar fayllarni lokalda yuklab olmasdan hisobotni ko'rib chiqadilar.
Golden qachon yangilanishi kerak — faqat UI-ning ongli o'zgarishidan so'ng. Shrift, rang, bo'shliq, ikonka o'zgarishi — golden yangilanishi kerak. Yangi tugma qo'shish, elementlarni joylashtirish — golden yangilanishi kerak. Ko'rinishni o'zgartiruvchi xatoni tuzatish — golden yangilanishi kerak. UI o'zgarishisiz refaktoring — golden yangilanmasligi kerak. Golden UI kodi o'zgarishisiz o'zgarsa — bu muhit sababli flaky test, sababni CI agentlarida yoki bog'liqlik versiyalarida qidiring.
Tez-tez beriladigan savollar
Golden Test — unit-test muhitida komponent darajasida snapshot-test (tez, emulatorsiz). Screenshot Test — qurilmada yoki emulatorda butun ekranni olish (sekin, ammo realistik). Golden off-screen bufer bilan ishlaydi, screenshot — haqiqiy displey bilan. Golden har bir commitda CI uchun mos, screenshot — chiqarishdan oldin nightly uchun.
Asosiy sabablar: (1) CI-da turli GPU — bir xil CI agentlaridan foydalaning. (2) Turli shrift versiyalari — OS versiyasini belgilang. (3) Turli anti-aliasing — threshold-ni sozlang (Roborazzi, iOSSnapshotTestCase). (4) Animatsiyalar — testlarda animatsiyalarni o'chiring. (5) Tizim elementlari (holat paneli) — ramkasiz device config dan foydalaning. Paparazzi Layoutlib tufayli flakiness-ga moyil emas.
Ha. Paparazzi paparazzi.snapshot { } orqali Compose-ni qo'llab-quvvatlaydi. Roborazzi ham Compose-ni qo'llab-quvvatlaydi. iOS-da SwiftSnapshotTesting UIHostingController orqali SwiftUI bilan ishlaydi. Compose komponentlari Layoutlib orqali, SwiftUI — UIKit renderi orqali ko'rsatiladi. Cheklov: Compose va SwiftUI animatsiyalari qo'llab-quvvatlanmaydi — golden-test faqat boshlang'ich holatni oladi.
Hech qachon CI-da golden qabul qilishni avtomatlashtirmang. Faqat lokalda: dasturchi katalogdan eski golden fayllarini o'chiradi va testlarni record bayrog'i bilan ishga tushiradi (Paparazzi: record=true, SwiftSnapshotTesting: record=true). Golden fayllari qayta yaratiladi. Dasturchi har bir golden-ni to'g'riligini tekshiradi, o'zgarishlarni kod bilan birga commit qiladi. CI-da avtomatik qabul qilish UI xatolarini o'tkazib yuborishga olib keladi.
Golden-testlar instrumental testlardan (UI Automator, XCUITest) tezroq. Bitta golden-test 50-200 ms da bajariladi (Paparazzi: o'rtacha MacBook Pro da 100-150 ms). 500 golden-test = 25-100 soniya. Emulator orqali screenshot-testlar bilan solishtiring: test boshiga 5-30 soniya. Golden-testlar qurilishni sekinlashtirmaydi: 100 test = ~15 soniya, bu pre-merge tekshiruvi uchun maqbul.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.