Snapshot test — bu foydalanuvchi interfeysini avtomatik tekshirish usuli bo‘lib, unda ekranning joriy holati testning oldingi ishga tushirilishida saqlangan etalon tasvir (snapshot) bilan taqqoslanadi. Har qanday vizual farq ishlab chiquvchining tasdiqlashini talab qiladigan o‘zgarish sifatida qayd etiladi. Elementlarning mavjudligini tekshiradigan UI testlardan farqli o‘laroq, snapshot testlar piksel o‘zgarishlarini — siljishlarni, rang og‘ishlarini va tartib buzilishlarini qayd etadi. Android Developers, 2024 ma’lumotlariga ko‘ra, snapshot test an’anaviy UI testlar tomonidan o‘tkazib yuborilgan vizual regressiyalarning 30% gachaini aniqlaydi, bu esa uni izchil interfeysni saqlash uchun ajralmas vositaga aylantiradi.
Asosiy ma’lumotlar
Snapshot test — test interfeys komponentini render qilib, olingan tasvirni etalon sifatida saqlaydigan va keyingi ishga tushirishlarda joriy renderni shu etalon bilan taqqoslaydigan texnikadir. Tasvirlar mos kelsa — test o‘tadi. Farqlar topilsa — test muvaffaqiyatsiz bo‘ladi va ishlab chiquvchi o‘zgartirilgan piksellar ajratib ko‘rsatilgan diff tasvirini oladi. Texnika veb-ishlanmadan (Jest snapshotlari) olingan va mobil platformalar üçün moslashtirilgan.
Snapshot testlarning asosiy qiymati kutilmagan vizual o‘zgarishlarni avtomatik aniqlashdir. Ishlab chiquvchi global temada rang sxemasini o‘zgartirib, tasodifan o‘nlab ekranlarga ta’sir qilishi mumkin. Tugmalar va matnlarning mavjudligini tekshiradigan UI testlar buni sezmaydi. Snapshot test har bir ta’sirlangan ekranda har bir pikselning o‘zgarishini qayd etib, o‘zgarishning to‘liq ta’sirini ko‘rsatadi.
Mobile DevOps Summit 2023 so‘roviga ko‘ra, klassik UI testlarga qo‘shimcha ravishda snapshot testdan foydalanadigan jamoalar nashrlardagi vizual nuqsonlar sonini 40% ga kamaytiradi. Bu yondashuv ayniqsa dizayn tizimlari va komponent yondashuvi bo‘lgan loyihalarda samarali, chunki bitta asosiy komponentning o‘zgarishi o‘nlab ekranlarga ta’sir qilishi mumkin.
Asosiy farq tekshirish obektidadir. UI testlari interfeys elementlarining mavjudligi, holati va xatti-harakatini tekshiradi: “tugma ko‘rinadi”, “matn xato xabarini o‘z ichiga oladi”, “bosilgandan so‘ng yangi ekran ochiladi”. Snapshot testlar tashqi ko‘rinishni yaxlit holda tekshiradi: elementlarning joylashishi, bo‘shliqlar, ranglar, shriftlar, soyalar va yumaloqlashtirishlar. Snapshot test “ekran kutilganidek ko‘rinadimi?” degan savolga javob beradi, UI test esa “ekran kutilganidek ishlaydimi?”
Ishlash tezligi ham farq qiladi. UI testlari emulyator yoki haqiqiy qurilmada ishlaydi, ilovaning to‘liq yuklanishini talab qiladi va bitta stsenariy üçün 10 soniyadan bir daqiqagacha vaqt oladi. Paparazzi kabi kutubxonalarga asoslangan snapshot testlar emulyatorni ishga tushirmasdan komponentni virtual muhitda render qiladi, test vaqtini 100–500 millisekundgacha qisqartiradi. To‘liq snapshot test to‘plami (50–100 ekran) 2–5 daqiqada bajariladi, xuddi shu hajmdagi UI testlar esa 30–60 daqiqa vaqt oladi.
Biroq snapshot testlar UI testlarni almashtirmaydi. Optimal strategiya — kombinatsiya: snapshot testlar vizual regressiyani (har bir ekranning asosiy holatlarda renderi), UI testlar esa xatti-harakat regressiyasini (bosish stsenariylari, kiritish validatsiyasi, navigatsiya) qamrab oladi. Bunday kombinatsiya minimal CI bajarish vaqtida interfeysning to‘g‘riligiga 90% ishonch beradi.
Android-da asosiy vositalar Paparazzi va Shot hisoblanadi. Cash App dan Paparazzi Layoutlib gravitatsion tartibidan foydalanib, emulyatorsiz JVM-da test muhitida komponentlarni render qiladi. Karumi dan Shot haqiqiy qurilma yoki emulyatorda Instrumentation skrinshotlarini oladi va ularni AShot kutubxonasi orqali etalonlar bilan taqqoslaydi, rezolyutsiya va piksel zichligi farqlarini hisobga oladi.
Paparazzi emulyatorni ishga tushirishni talab qilmaydi — render Layoutlib orqali JVM-da bajariladi, bu esa birlik testlari bilan solishtirish mumkin bo‘lgan tezlikni beradi. Kutubxona ham View tizimini, ham Jetpack Compose-ni qo‘llab-quvvatlaydi. Compose üçün paparazzi.snapshot { MyComposable() } modifikatoridan foydalaniladi. Etalonlar src/test/snapshots papkasida saqlanadi va har bir ishga tushirishda avtomatik taqqoslanadi. Maksimal farq foizi maxPercentDifference orqali sozlanadi.
SnapshotTesting Point-Free dan nafaqat UIImage, balki satrlar, JSON, Data va to‘liq Core Data omborlarini ham taqqoslashni qo‘llab-quvvatlaydi. Bu uni nafaqat UI snapshotlari üçün, balki JSON javoblarining serializatsiyasi va dekodlanishini tekshirish üçün ham universal vositaga aylantiradi. SwiftUI üçün .image(on: .iPhone13) modifikatori bilan assertSnapshot kengaytmasidan foydalaniladi. record: true yozish strategiyasi birinchi ishga tushirishda etalonlarni yaratadi.
React Native üçün react-native-testing-library jest-image-snapshot bilan birgalikda mashhur yechimdir. Snapshot testga veb yondashuvi komponentlarni Node.js muhitida render qilish va virtual DOM ning JSON skrinshotlarini keyingi taqqoslash orqali mobil muhitga ko‘chiriladi. Bu yondashuv natividan tezroq, ammo kamroq aniqlikda — shriftlar va tizim komponentlarini renderlashning platforma xususiyatlarini hisobga olmaydi. Flutter üçün goldens toolkit orqali golden testing dan foydalaniladi.
Android (Paparazzi) va iOS (SnapshotTesting) üçün snapshot testlarni ko‘rib chiqamiz. Ikkala misol komponentning — avatar, ism va statusga ega foydalanuvchi kartasining tashqi ko‘rinishini tekshiradi. Test komponentni test ma’lumotlari bilan render qiladi va natijani repozitoriyada saqlangan etalon tasvir bilan taqqoslaydi.
Paparazzi renderni olish üçün @Test annotatsiyasi va snapshot() metodidan foydalanadi. Etalonlar src/test/snapshots papkasida saqlanadi va keyingi ishga tushirishda taqqoslash üçün avtomatik olinadi.
class UserCardSnapshotTest {
@get:Rule
val paparazzi = Paparazzi(
theme = "Theme.MyApp",
maxPercentDifference = 0.1
)
@Test
fun userCard_defaultState() {
val card = UserCard(
name = "Alice Johnson",
status = "Online",
avatarUrl = "https://example.com/avatar.png"
)
paparazzi.snapshot(card)
}
@Test
fun userCard_offlineState() {
val card = UserCard(
name = "Bob Smith",
status = "Offline",
avatarUrl = null
)
paparazzi.snapshot(card, name = "user_card_offline")
}
}
SnapshotTesting assertSnapshot ichida .snapshot() modifikatoridan foydalanadi. Kutubxona formatni avtomatik aniqlaydi — UIView üçün UIImage, matn üçün String, ikkilik ma’lumotlar üçün Data.
import SnapshotTesting
import XCTest
class UserCardSnapshotTests: XCTestCase {
func testUserCardDefaultState() {
let card = UserCardView(
name: "Alice Johnson",
status: "Online",
avatarURL: URL(string: "https://example.com/avatar.png")
)
let controller = UIHostingController(rootView: card)
assertSnapshot(matching: controller, as: .image(on: .iPhone13))
}
func testUserCardOfflineState() {
let card = UserCardView(
name: "Bob Smith",
status: "Offline",
avatarURL: nil
)
assertSnapshot(matching: card, as: .image(on: .iPhone13))
}
}
Odatiy ish jarayoni to‘rt bosqichni o‘z ichiga oladi. Birinchi ishga tushirish (record mode): barcha snapshot testlar yozish rejimida bajariladi — etalon tasvirlar yaratiladi va repozitoriyada saqlanadi. Bu bosqich testlarning dastlabki sozlamasida yoki interfeysning ongli o‘zgarishidan so‘ng amalga oshiriladi. Yozilgandan so‘ng, etalonlar kod bilan birga commit qilinadi — ular loyihaning bir qismiga aylanadi.
Keyingi ishga tushirishlarda testlar taqqoslash rejimida ishlaydi: har bir yangi render etalon bilan taqqoslanadi. Farqlar topilsa, diff tasviri yaratiladi: etalonga mos keladigan piksellar yashil rangda, farqlanadiganlari esa qizil rangda ajratib ko‘rsatiladi. Ishlab chiquvchi diff-ni o‘rganadi va qaror qabul qiladi: agar o‘zgarish kutilgan bo‘lsa (dizaynning ongli o‘zgarishi), etalon record buyrug‘i bilan yangilanadi; agar kutilmagan bo‘lsa — xato tuzatiladi. Etalonlarni yangilash bir martalik buyruq bilan amalga oshiriladi: Paparazzi üçün `./gradlew recordPaparazzi`, SnapshotTesting üçün `assertSnapshot(record: true)`.
Spotify Engineering Blog (2022) ma’lumotlariga ko‘ra, tavsiflangan ish jarayonidan foydalanadigan jamoalar diff tasvirlarini tahlil qilishga har bir test üçün o‘rtacha 2 daqiqa sarflaydi. 50 ta snapshot testdan iborat to‘plamda to‘liq etalon yangilash sikli 15–20 daqiqa davom etadi, bu 50 ekranda vizual o‘zgarishlarni qo‘lda tekshirishdan ancha tezroq.
Snapshot testlarning asosiy cheklovlari bor. Muhitga sezgirlik: bir xil komponent turli OT versiyalarida, ekran zichliklarida va shrift konfiguratsiyalarida turlicha renderlanishi mumkin. Bir mashinada yaratilgan etalonlar CI serveridagi renderdan farq qilishi mumkin. Yechim — qat’iy muhit parametrlaridan foydalanish: Paparazzi üçün aniq Layoutlib versiyasi yoki SnapshotTesting üçün aniq qurilma modeli.
Anti-na’muna 1: ulkan snapshotlar — butun ekranni qamrab olgan snapshot test har qanday komponentning minimal o‘zgarishida muvaffaqiyatsiz bo‘ladi. To‘g‘ri yondashuv — alohida komponentlarni (tugma, karta, kiritish maydoni) izolyatsiya qilingan holda test qilish. Har bir komponent mustaqil test qilinadi, bu esa o‘zgarish manbasiga aniq ishora beradi. Anti-na’muna 2: diff-larni e’tiborsiz qoldirish — diff tasvirlarini tahlil qilmasdan etalonlarni avtomatik yangilash snapshot testlarning qiymatini nolga tushiradi. Har bir diff ishlab chiquvchining ongli qarorini talab qiladi.
Better Engineering Blog (2023) ma’lumotlariga ko‘ra, snapshot testlar dizayn tizimi komponentlari va asosiy ekranlarning bo‘sh, to‘ldirilgan, xato va chegara holatlarida qamrab olinishida eng katta foyda keltiradi. Animatsiyalar va dinamik holatlarni snapshot testlar bilan qamrab olish renderdagi vaqt belgilarining noaniqligi sababli samarasiz — bunday stsenariylar üçün video yozuv yoki qo‘lda QA tekshiruvi ko‘proq mos keladi.
Ko‘p beriladigan savollar
Yo‘q, snapshot testlar tashqi ko‘rinishni, UI testlar esa interfeysning xatti-harakatini tekshiradi. Optimal strategiya — ikkala yondashuvni birlashtirish: snapshotlar vizual regressiya üçün, UI testlar stsenariylar va navigatsiyani tekshirish üçün. Snapshotlar “to‘g‘ri ko‘rinadimi?” degan savolga, UI testlar “to‘g‘ri ishlaydimi?” degan savolga javob beradi.
Etalonlar dizayndagi har bir ongli o‘zgarishda yangilanadi: yangi tema rangi, o‘zgartirilgan bo‘shliqlar, elementlarning qo‘shilishi yoki olib tashlanishi. Yangilash record rejimi orqali amalga oshiriladi, so‘ngra diff tasvirlari code review da tekshiriladi, o‘zgarishlar dizaynerning kutganlariga mos kelishiga ishonch hosil qilish üçün.
Birinchi navbatda dizayn tizimi komponentlari — tugmalar, kartalar, kiritish maydonlari, modal oynalar. Keyin asosiy ekranlar asosiy holatlarda. Snapshotlar bilan test qilmang animatsiyalarni, WebView-ni, xaritalarni va dinamik kontentli ekranlarni — ular üçün snapshotlar noaniqlik sababli yolg‘on xatolarga olib keladi.
Record va test rejimlari üçün bir xil API darajasidan foydalaning. Paparazzi üçün konfiguratsiyada aniq Layoutlib versiyasini belgilang. SnapshotTesting üçün qurilma modelini qat’iylashtiring. Android 14 da yaratilgan etalonlar Android 12 dagi renderdan tizim shriftlari va Material mavzusidagi o‘zgarishlar sababli farq qilishi mumkin.
CI da snapshot testlar tekshirish rejimida (verify) ishlaydi. Test muvaffaqiyatsiz bo‘lsa, CI qurilish artefaktlarida diff tasvirini ko‘rsatadi. Record rejimi (etalonlarni yangilash) ishlab chiquvchi tomonidan lokalda yoki alohida CI topshirig‘ida qo‘lda ishga tushirilgan holda bajariladi. Etalon tasvirlar majburiy ravishda repozitoriyada commit qilinadi.
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.