Golden Test (سنیپ شاٹ ٹیسٹ، ریفرنس ٹیسٹنگ) — UI کے بصری ٹیسٹ کا ایک طریقہ جس میں موجودہ کمپوننٹ رینڈر کا پہلے سے محفوظ کردہ ریفرنس امیج (golden فائل) سے موازنہ کیا جاتا ہے۔ اگر پکسل تبدیلیاں مقررہ حد سے تجاوز کر جائیں، تو ٹیسٹ ناکام ہو جاتا ہے اور diff امیج جنریٹ کرتا ہے۔ ڈیولپر diff کا جائزہ لیتا ہے اور یا تو تبدیلیاں قبول کرتا ہے (golden اپ ڈیٹ کرتا ہے) یا بگ ٹھیک کرتا ہے۔ مزید پڑھیں Paparazzi کے بارے میں Meta Engineering مضمون میں۔
اہم نکات
Golden Test — ایک کمپوننٹ کی بصری ظاہری شکل کی ریفرنس سے پکسل بہ پکسل موازنہ کر کے خودکار جانچ ہے۔ عمل: (1) ڈیولپر یا ٹیسٹر کمپوننٹ کا پہلا سنیپ شاٹ بناتا ہے — یہ «golden» (ریفرنس) ہے۔ (2) golden فائل ٹیسٹ کے ساتھ ریپوزٹری میں محفوظ کی جاتی ہے۔ (3) بعد کے رنز میں، ٹیسٹ کمپوننٹ کو دوبارہ رینڈر کرتا ہے اور محفوظ کردہ golden سے موازنہ کرتا ہے۔ (4) اگر امیجز مماثل ہوں — ٹیسٹ پاس۔ اگر مختلف ہوں — ٹیسٹ فیل اور diff دکھاتا ہے۔ فیصلہ: یا تو تبدیلیاں متوقع ہیں (golden اپ ڈیٹ کریں) یا یہ بگ ہے۔
Golden کیسے جنریٹ ہوتا ہے — لائبریری کمپوننٹ کو حقیقی ڈسپلے کے بغیر آف اسکرین بفر (Android: Canvas، iOS: UIGraphicsImageRenderer) میں رینڈر کرتی ہے۔ اس کا مطلب ہے کہ golden ٹیسٹ اسکرین ایمولیٹر (ورچوئل ڈسپلے) کے بغیر CI پر کام کرتے ہیں، جس سے عملدرآمد تیز ہوتا ہے۔ Android پر Paparazzi Android Studio کا Layoutlib استعمال کرتا ہے — وہی انجن جو Layout Editor استعمال کرتا ہے۔ iOSSnapshotTestCase CGImage میں UIKit رینڈرنگ استعمال کرتا ہے۔ نتیجہ — مقررہ سائز کی PNG فائل۔
Golden فائلیں — ایک اسکرین (1080x1920) کا PNG سنیپ شاٹ پیچیدگی کے لحاظ سے 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 ٹیسٹ — golden ٹیسٹ کا بنیادی مسئلہ۔ مختلف GPU، فونٹ ورژن اور اینٹی ایلائسنگ پکسلز میں باریک فرق پیدا کرتے ہیں۔ حل: حد (مختلف پکسلز کا قابل اجازت فیصد)، فزی موازنہ، اور ایک جیسے CI ایجنٹس پر چلانا (ایک ہی GPU، OS، ایمولیٹر ورژن)۔ Paparazzi پکسل پرفیکٹ موازنہ استعمال کرتا ہے، اس لیے CI ایجنٹس ایک جیسے ہونے چاہئیں۔
Golden Test — مقررہ ریفرنس کے ساتھ اسکرین شاٹ ٹیسٹنگ کی ایک قسم ہے۔ «golden» کی اصطلاح کا مطلب ہے کہ ریفرنس کو ٹیم نے منظور کیا ہے اور ریپوزٹری میں محفوظ ہے۔ کسی بھی امیج تبدیلی کے لیے ڈیولپر کے شعوری فیصلے کی ضرورت ہوتی ہے: golden اپ ڈیٹ کریں یا کوڈ ٹھیک کریں۔ Golden Test انفرادی کمپوننٹس (Composable، UIView) کی سطح پر کام کرتا ہے اور حقیقی ڈیوائس کی ضرورت نہیں ہوتی۔
Screenshot Test — ایک وسیع تر تصور ہے۔ اسکرین شاٹ ٹیسٹ حقیقی ڈیٹا، نیویگیشن، سسٹم اسٹیٹس بار اور اینیمیشنز کے ساتھ پوری اسکرین کیپچر کر سکتا ہے۔ اسکرین شاٹ ٹیسٹ اکثر حقیقی ڈیوائس یا ایمولیٹر پر UI Automator (Android) یا XCUITest (iOS) کے ذریعے چلائے جاتے ہیں۔ Golden ٹیسٹ یونٹ ٹیسٹ ماحول (JVM، XCTest) میں ایمولیٹر کے بغیر چلتے ہیں اور صرف ایک کمپوننٹ کیپچر کرتے ہیں۔
| خصوصیت | Golden Test | Screenshot Test |
|---|---|---|
| سطح | کمپوننٹ/Composable/View | پوری اسکرین |
| ماحول | یونٹ ٹیسٹ (آف اسکرین بفر) | ڈیوائس/ایمولیٹر |
| رفتار | 50–200 ms فی ٹیسٹ | 2–30 سیکنڈ فی ٹیسٹ |
| اینیمیشنز | معاون نہیں | معاون (توقف کے ساتھ) |
| CI بغیر GPU | کام کرتا ہے (Layoutlib) | ایمولیٹر چاہیے |
| سیٹ اپ پیچیدگی | کم | زیادہ (ایمولیٹر/Device Farm) |
| عدم استحکام | درمیانی (مختلف GPU) | زیادہ (ایمولیٹر، وقت) |
Golden بمقابلہ Screenshot — ہر کمٹ پر انفرادی UI کمپوننٹس (بٹن، کارڈ، ڈائیلاگ) کی جانچ کے لیے golden ٹیسٹ۔ ریلیز سے پہلے پوری اسکرینز کی E2E جانچ کے لیے اسکرین شاٹ ٹیسٹ۔ Golden ٹیسٹ ڈیولپر کو تیز فیڈبیک دیتے ہیں، اسکرین شاٹ ٹیسٹ پوری ایپلیکیشن کی سالمیت میں اعتماد دیتے ہیں۔ IT Sectr میں ہم Pull Request کے لیے golden ٹیسٹ (3–5 منٹ) اور راتوں رات اسکرین شاٹ ٹیسٹ (30–60 منٹ) استعمال کرتے ہیں۔
Paparazzi — Cash App (Square) کی لائبریری جو Android View اور Jetpack Compose کمپوننٹس کو ایمولیٹر کے بغیر PNG میں رینڈر کرتی ہے۔ یہ Layoutlib (Android Studio Preview کا وہی انجن) استعمال کرتی ہے۔ سیٹ اپ: Gradle پلگ ان شامل کریں، @Test اور @RunWith(PaparazziRule::class) کے ساتھ ٹیسٹ لکھیں، paparazzi.snapshot(view) کال کریں۔ Paparazzi اینیمیشنز، ویڈیو اور Real Device کو سپورٹ نہیں کرتا — صرف جامد کمپوننٹ رینڈرنگ۔
// build.gradle.kts (module)
plugins {
id("app.cash.paparazzi") version "1.3.1"
}
// Compose کمپوننٹ کے لیے 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 اور امیج موازنہ کی حمایت کے ساتھ Paparazzi کا متبادل۔ فرق: Roborazzi Robolectric کے ذریعے کام کرتا ہے اور حد (قابل اجازت پکسل فرق فیصد) کو سپورٹ کرتا ہے۔ یہ CI پر مختلف GPU کے ساتھ عدم استحکام کم کرتا ہے۔ Roborazzi تبدیلیوں کی GIF اینیمیشن (پہلے/بعد/diff) بھی بنا سکتا ہے، جو کوڈ ریویو کے لیے آسان ہے۔ فائل فارمیٹ: PNG + JSON میٹا ڈیٹا۔
Golden اپ ڈیٹ کرنا — جان بوجھ کر UI تبدیلی کے بعد، ڈیولپر پرانی golden فائلیں حذف کرتا ہے اور record فلیگ کے ساتھ ٹیسٹ چلاتا ہے۔ Paparazzi تمام golden فائلیں دوبارہ بناتا ہے۔ پھر ڈیولپر کوڈ تبدیلی کے ساتھ نئی golden فائلیں کمٹ کرتا ہے۔ کوڈ ریویو میں، ریویو کرنے والا پرانی اور نئی golden فائلوں کا diff دیکھتا ہے۔ اگر تبدیلیاں منظور ہو جائیں — PR مرج ہو جاتا ہے۔ اگر نہیں — ڈیولپر کوڈ ٹھیک کرتا ہے اور ٹیسٹ دوبارہ چلاتا ہے۔ CI پر golden فائلوں کو کبھی خودکار طور پر اپ ڈیٹ نہ کریں — صرف مقامی طور پر۔
SwiftSnapshotTesting — pointfree.co کی لائبریری، Composable Architecture کے تخلیق کار۔ UIView، UIViewController، CALayer اور SwiftUI View کو سپورٹ کرتی ہے۔ اصول: assertSnapshot(matching: view, as: .image)۔ پہلے رن پر، golden خود بخود بنتا ہے۔ بعد کے رنز پر، موازنہ کیا جاتا ہے۔ اگر فرق قابل اجازت حد سے زیادہ ہو، ٹیسٹ ناکام ہو جاتا ہے۔ SwiftSnapshotTesting UIGraphicsImageRenderer کے ذریعے کام کرتا ہے، جو CI (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 (سابقہ FBSnapshotTestCase) — Uber کی UIKit کے لیے لائبریری۔ SwiftSnapshotTesting کے برعکس، iOSSnapshotTestCase کو اسکرین سائز اور اورینٹیشن بتانے کی ضرورت ہوتی ہے۔ Golden فائلیں ReferenceImages فولڈر میں PNG ہیں۔ فائدہ: SwiftUI کے بغیر UIKit کے ساتھ کام کرتی ہے اور iOS 12+ کو سپورٹ کرتی ہے۔ نقصان: golden خود بخود اپ ڈیٹ نہیں کرتی — record فلیگ کے ساتھ چلانی پڑتی ہے۔ SwiftSnapshotTesting زیادہ جدید ہے اور نئے پروجیکٹس کے لیے تجویز کردہ ہے۔
ڈیوائس کے مخصوص golden — مختلف اسکرین سائز اور اورینٹیشن کے لیے golden فائلیں مختلف ہوتی ہیں۔ معیاری طریقہ: golden فائلوں کو TestName@3x~iPhone14.png کے نام سے نامزد کریں۔ SwiftSnapshotTesting خود بخود ڈیوائس سفیكس شامل کرتا ہے اگر .image(on: .iPhoneSe) پیرامیٹر بتایا گیا ہو۔ Android پر، Paparazzi سائز سیٹ کرنے کے لیے DeviceConfig استعمال کرتا ہے۔ ہر معاون ڈیوائس فارم فیکٹر کے لیے golden علیحدہ سے اسٹور کریں۔ مختلف سائز کے لیے ایک golden استعمال نہ کریں — یہ غیر مستحکم ٹیسٹ کا باعث بنے گا۔
CI پائپ لائن — golden ٹیسٹ ہر Pull Request پر چلنے چاہئیں۔ اگر کوئی ٹیسٹ ناکام ہوتا ہے، CI diff امیج کو بلڈ آرٹیفیکٹ کے طور پر دکھاتا ہے۔ ڈیولپر diff کا جائزہ لیتا ہے اور فیصلہ کرتا ہے۔ اہم: CI پر جنریٹ کردہ golden فائلیں کبھی خودکار طور پر کمٹ نہیں ہوتیں۔ صرف جان بوجھ کر تبدیلی کے بعد ڈیولپر کے ذریعے مقامی جنریشن۔ GitHub Actions اور GitLab CI براؤزر میں diff دیکھنے کے لیے آرٹیفیکٹ (png، html) اپ لوڈ کرنے کی حمایت کرتے ہیں۔
ریپوزٹری کا سائز — golden فائلیں تیزی سے بڑھتی ہیں۔ 500 ٹیسٹ = 100–400 MB PNG۔ حل: (1) Git LFS — ہر golden LFS میں محفوظ، صرف checkout پر کلون ہوتا ہے۔ (2) golden کو علیحدہ ریپوزٹری میں اسٹور کریں اور سب ماڈیول کے طور پر شامل کریں۔ (3) S3 + کیشنگ — golden S3 پر، CI چیکسم کے ذریعے صرف تبدیل شدہ فائلیں ڈاؤن لوڈ کرتا ہے۔ IT Sectr میں ہم track *.png filter=lfs diff=lfs merge=lfs text=false کے ساتھ Git LFS استعمال کرتے ہیں۔ مقامی طور پر، golden src/test/goldens/ میں ہیں۔
Golden کا کوڈ ریویو — عام git diff PNG تبدیلیاں نہیں دکھاتا۔ حل: (1) GitHub کلک کرنے پر PNG امیجز کھولتا ہے۔ (2) Review Apps استعمال کریں جہاں golden diff براؤزر میں دکھائی دیتا ہے۔ (3) پہلے/بعد/diff کالم کے ساتھ HTML رپورٹ جنریٹ کریں۔ Paparazzi تین کالم والی HTML رپورٹ بناتا ہے: حقیقی، متوقع، diff۔ رپورٹ CI آرٹیفیکٹ سے منسلک ہوتی ہے۔ ریویو کرنے والے فائلیں مقامی طور پر ڈاؤن لوڈ کیے بغیر رپورٹ دیکھتے ہیں۔
Golden کب اپ ڈیٹ کریں — صرف شعوری UI تبدیلی کے بعد۔ فونٹ، رنگ، پیڈنگ، آئیکن تبدیل کرنا — golden اپ ڈیٹ ہونا چاہیے۔ نیا بٹن شامل کرنا، عناصر کو دوبارہ ترتیب دینا — golden اپ ڈیٹ ہونا چاہیے۔ بگ فکس جو بصری ظاہری شکل بدلتا ہے — golden اپ ڈیٹ ہونا چاہیے۔ UI تبدیلی کے بغیر ریفیکٹرنگ — golden نہیں بدلنا چاہیے۔ اگر golden UI کوڈ تبدیلی کے بغیر بدلتا ہے — یہ ماحول کی وجہ سے flaky ٹیسٹ ہے، CI ایجنٹس یا ڈیپنڈنسی ورژن میں وجہ تلاش کریں۔
اکثر پوچھے گئے سوالات
Golden Test — یونٹ ٹیسٹ ماحول میں کمپوننٹ سطح پر سنیپ شاٹ ٹیسٹ (تیز، ایمولیٹر کے بغیر)۔ Screenshot Test — ڈیوائس یا ایمولیٹر پر پوری اسکرین کیپچر کرتا ہے (سست، لیکن حقیقت پسندانہ)۔ Golden آف اسکرین بفر کے ساتھ کام کرتا ہے، screenshot حقیقی ڈسپلے کے ساتھ۔ Golden ہر کمٹ پر CI کے لیے موزوں، screenshot ریلیز سے پہلے راتوں رات رنز کے لیے۔
بنیادی وجوہات: (1) CI پر مختلف GPU — ایک جیسے CI ایجنٹس استعمال کریں۔ (2) مختلف فونٹ ورژن — OS ورژن فکس کریں۔ (3) مختلف اینٹی ایلائسنگ — حد مقرر کریں (Roborazzi، iOSSnapshotTestCase)۔ (4) اینیمیشنز — ٹیسٹ میں اینیمیشنز بند کریں۔ (5) سسٹم عناصر (اسٹیٹس بار) — بغیر فریم والی ڈیوائس کنفیگریشن استعمال کریں۔ Paparazzi Layoutlib کی وجہ سے عدم استحکام کا شکار نہیں ہے۔
جی ہاں۔ Paparazzi میں paparazzi.snapshot { } کے ذریعے Compose کے لیے بلٹ ان سپورٹ ہے۔ Roborazzi بھی Compose کو سپورٹ کرتا ہے۔ iOS پر، SwiftSnapshotTesting UIHostingController کے ذریعے SwiftUI کے ساتھ کام کرتا ہے۔ Compose کمپوننٹس Layoutlib کے ذریعے رینڈر ہوتے ہیں، SwiftUI UIKit رینڈرنگ کے ذریعے۔ حد: Compose اور SwiftUI اینیمیشنز معاون نہیں ہیں — golden ٹیسٹ صرف ابتدائی حالت کیپچر کرتا ہے۔
CI پر golden قبولیت کو کبھی خودکار نہ کریں۔ صرف مقامی طور پر: ڈیولپر ڈائریکٹری سے پرانی golden فائلیں حذف کرتا ہے اور record فلیگ کے ساتھ ٹیسٹ چلاتا ہے (Paparazzi: record=true، SwiftSnapshotTesting: record=true)۔ Golden فائلیں دوبارہ بنتی ہیں۔ ڈیولپر ہر golden کی درستگی چیک کرتا ہے، کوڈ کے ساتھ تبدیلیاں کمٹ کرتا ہے۔ CI پر خودکار قبولیت UI بگز کو نظر انداز کرنے کا باعث بنے گی۔
Golden ٹیسٹ انسٹرومینٹڈ ٹیسٹ (UI Automator، XCUITest) سے تیز ہیں۔ ایک golden ٹیسٹ 50–200 ms میں انجام پاتا ہے (Paparazzi: اوسط MacBook Pro پر 100–150 ms)۔ 500 golden ٹیسٹ = 25–100 سیکنڈ۔ ایمولیٹر کے ذریعے اسکرین شاٹ ٹیسٹ سے موازنہ کریں: 5–30 سیکنڈ فی ٹیسٹ۔ Golden ٹیسٹ بلڈ کو سست نہیں کرتے: 100 ٹیسٹ = ~15 سیکنڈ، جو مرج سے پہلے کی جانچ کے لیے قابل قبول ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں