Screenshot Test — بررسی خودکار رابط کاربری از طریق ذخیره و مقایسه کردن عکسهای صفحه اپلیکیشن با تصاویر مرجع. بر خلاف تستهای golden، تستهای screenshot بر روی دستگاههای واقعی یا شبیهسازها انجام میشوند، صفحات کامل با ناوبری، عناصر سیستمی و انیمیشنها را ذخیره میکنند و از UI Automator (Android) یا XCUITest (iOS) برای تعامل با اپلیکیشن استفاده میکنند. جزئیات بیشتر — در مستندات Android UI Automator.
نکات کلیدی
Screenshot Test — آزمایش end-to-end رابط کاربری است که در آن تست صفحه اپلیکیشن را باز میکند، عملیاتی انجام میدهد (لمس، ورود متن، اسکرول) و از وضعیت به دست آمده عکس صفحه میگیرد. عکس صفحه با مرجع (baseline) ذخیره شده در رپوزیتوری مقایسه میشود. اگر عکسهای صفحه متفاوت باشند — تست مردود میشود. تستهای screenshot رگرسیونهای بصری را که در تستهای واحد مشاهده نمیشوند تشخیص میدهند: فاصلههای نادرست، تداخل عناصر، رنگهای نادرست.
چرا تستهای screenshot با وجود تستهای golden — تستهای golden کامپوننتها را به صورت جداگانه بررسی میکنند: یک دکمه، یک کارت، یک متن. تستهای screenshot کامل صفحه را در محیطی تا حد امکان نزدیک به تولید بررسی میکنند: ناوبری واقعی، دادههای واقعی (یا ماکهای حداکثر واقعگرایانه)، فونتهای واقعی سیستم، نوار وضعیت واقعی. تنها تست screenshot نشان میدهد که دکمه با عنصری دیگر بر روی دستگاه واقعی تداخل دارد.
ارزش تجاری — به گزارش Google (2023)، باگهای بصری 15-25% کل باگهای اپلیکیشنهای موبایل را تشکیل میدهند. تستهای screenshot بررسی کیفیت بصری را که قبلاً توسط مهندسان QA به صورت دستی انجام میشد خودکار میکنند. یک تست screenshot جایگزین 5-10 دقیقه تست دستی یک صفحه است. برای یک اپلیکیشن با 50 صفحه صرفهجویی: 4-8 نفر-ساعت برای یک اجرای رگرسیون. تستهای screenshot پس از 2-3 چرخه انتشار بازگردان دهنده هستند.
تستهای golden سریعتر و سادهتر هستند: رندر کامپوننت در بافر off-screen چند میلیثانیه طول میکشد، به دستگاه نیازی ندارد، در CI پایدار هستند. تستهای screenshot واقعگرایانهتر هستند: صفحه واقعی با عناصر سیستمی را ذخیره میکنند، از انیمیشنها و ناوبری پشتیبانی میکنند و بر روی دستگاههای واقعی کار میکنند. انتخاب به هدف بستگی دارد: بازخورد سریع برای توسعهدهنده (golden) یا واقعگرایی حداکثر قبل از انتشار (screenshot).
| ویژگی | Screenshot Test | Golden Test |
|---|---|---|
| سرعت | 2-30 ثانیه | 50-200 میلیثانیه |
| واقعگرایی | حداکثر (دستگاه واقعی) | محدود (off-screen) |
| نیازمند دستگاه | بله (شبیهساز/فیزیکی) | خیر (JVM, XCTest) |
| انیمیشنها | پشتیبانی میکند | پشتیبانی نمیکند |
| ناوبری | سناریوهای چند مرحلهای | یک کامپوننت |
| Flakiness | بالا (شبکه، زمانبندی) | متوسط (GPU، فونتها) |
| موازات | Device Farm (Firebase, AWS) | چند رشتهای JVM/XCTest |
Golden + Screenshot — از تستهای golden برای هر کامپوننت UI در کتابخانه کامپوننت (Design System) استفاده کنید. 80% رگرسیونهای بصری در سطح کامپوننت گیر افتاده میشوند. تستهای screenshot — برای مسیرهای حساس کاربر: معرفی، ورود، فرآیند پرداخت، سبد خرید. 20% رگرسیونهای مربوط به انتگراسیون کامپوننتها در صفحه واقعی تنها توسط تستهای screenshot گیر افتاده میشوند. در IT Sectr از نسبت 80/20 استفاده میکنیم: 400 golden + 100 screenshot.
وقتی تست screenshot نیاز نیست — اگر صفحه از محتوای استاتیک بدون تعامل تشکیل شده باشد، تست golden کامپوننت همان سطح بررسی را با هزینه کمتر ارائه میدهد. اگر صفحه به صورت پویا تغییر میکند (فید، چت)، تست screenshot نیازمند پیکربندی پیچیده دادهها و زمان انتظار است. در چنین مواردی از screenshot برای وضعیت پایه (لیست خالی، بارگیری) و golden برای کارتهای جداگانه در لیست استفاده کنید.
UI Automator — چارچوب Android برای تست UI چند برنامهای. امکان گرفتن عکس صفحه از طریق UiDevice.takeScreenshot() را فراهم میکند. بر خلاف Espresso (داخل یک برنامه کار میکند)، UI Automator میتواند با کادرهای سیستمی (اجازهها، اعلانها) و سایر برنامهها تعامل کند. تست screenshot با UI Automator: باز کردن اپلیکیشن، منتظر بارگیری شدن، گرفتن عکس صفحه، مقایسه با مرجع.
class LoginScreenScreenshotTest {
@get:Rule
val rule = ComposeTestRule.createAndroidComposeRule<MainActivity>()
@Test
fun login_screen_default() {
val device = UiDevice.getInstance(
InstrumentationRegistry.getInstrumentation()
)
// منتظر بارگذاری صفحه میمانیم
IdlingRegistry.getInstance().waitForIdle()
// اسکرینشات میگیریم
val screenshot = device.takeScreenshot()
val golden = loadGolden("login_default.png")
// با نسخه مرجع مقایسه میکنیم
val diff = ImageComparator.compare(screenshot, golden)
assertTrue(diff.similarity > 0.98)
}
}
Firebase Test Lab — خدمات Google Cloud برای اجرای تستهای ابزاری بر روی صدها دستگاه واقعی به صورت موازی. تستهای screenshot در Firebase Test Lab عکسهای صفحه را در دستگاههای مختلف (Pixel 7، Galaxy S24، Xiaomi 14) گرفته و با مراجع مقایسه میکنند. مزیت: یک تست UI را در 20 دستگاه در 10-15 دقیقه بررسی میکند. معیب: هزینه ($1-5 برای یک تست روی 20 دستگاه). Firebase Test Lab از طریق gcloud CLI یا افزونه Gradle با CI یکپارچه میشود.
Shot — کتابخانه برای تستهای screenshot در Android که ایجاد و مقایسه عکسهای صفحه را تسهیل میکند. Shot بر روی Espresso و UI Automator کار میکند و مدیریت golden (ایجاد، بهروزرسانی، حذف)، مقایسه با آستانه (پیکسل یا درصد) و تولید گزارش HTML را اضافه میکند. Shot برای پروژههایی که میخواهند بدون نوشتن زیرساخت مقایسه تصویر خود به سرعت تست screenshot را پیاده کنند مناسب است.
XCUITest — چارچوب Apple برای تست UI اپلیکیشنهای iOS، iPadOS و tvOS. تستهای screenshot در XCUITest از XCUIScreen.main.screenshot() برای ذخیره صفحه و XCAttachment برای ذخیره عکس صفحه استفاده میکنند. XCUITest اعمال کاربر را شبیهسازی میکند: tap, swipe, typeText و پس از هر مرحله عکس صفحه میگیرد. در Xcode 16+ پشتیبانی داخلی برای مقایسه عکسهای صفحه با مراجع از طریق XCTAttachment اضافه شده است.
final class LoginScreenScreenshotTests: XCTestCase {
var app: XCUIApplication!
override func setUp() {
super.setUp()
app = XCUIApplication()
app.launch()
}
func test_login_initial_state() {
let loginButton = app.buttons["login_button"]
XCTAssertTrue(loginButton.exists)
// اسکرینشات میگیریم
let screenshot = app.screenshot()
let attachment = XCTAttachment(screenshot: screenshot)
attachment.name = "Login-Screen-Initial"
attachment.lifetime = .keepAlways
add(attachment)
// مقایسه با نسخه مرجع (نیازمند XCTAttachment + golden)
assertScreenshot(
screenshot: screenshot,
goldenName: "login_initial_state"
)
}
}
Xcode Cloud — CI ابری از Apple برای ساخت و آزمایش اپلیکیشنهای iOS. Xcode Cloud از اجرای تستهای XCUITest بر روی شبیهسازها پشتیبانی میکند. تستهای screenshot را میتوان روی چندین شبیهساز به صورت موازی اجرا کرد (iPhone 15، iPhone 15 Pro Max، iPad Pro). نتایج: XCResult Bundle با پیوستها. Xcode Cloud در GitHub/GitLab جاسازی نشده است — از Xcode Cloud Webhooks برای یکپارچگی استفاده کنید. جایگزین: GitHub Actions با macos-14 و xcodebuild.
چارچوبهای مقایسه — iOSSnapshotTestCase (Uber) برای تستهای screenshot نیز اگر روی شبیهساز اجرا شوند کار میکنند. SwiftSnapshotTesting (pointfree) بیشتر متوجه تستهای golden کامپوننت است. برای تستهای screenshot در iOS از ابزارهای داخلی XCUITest + XCTAttachment + ImageComparator سفارشی (Pixelmator یا AImage) استفاده کنید. در CI از شبیهساز استفاده کنید — تستهای screenshot در دستگاههای واقعی تنها از طریق Device Farm (AWS Device Farm) کار میکنند.
مدیریت baseline — عکسهای مرجع در رپوزیتوری (Git LFS) یا S3 ذخیره میشوند. هر عکس صفحه بر اساس الگو نامگذاری میشود: {testName}_{device}_{orientation}_{locale}.png. مثال: loginScreenPixel7PortraitRu.png. با افزودن دستگاه یا locale جدید، baseline جدیدی ایجاد میشود. پس از تغییر UI، baselineهای قدیمی بعد از code review با نسخههای جدید جایگزین میشوند. Baseline بخشی از بازه کد است، همانند منابع تست.
CI Pipeline — (1) ساخت اپلیکیشن. (2) اجرای تستهای screenshot بر روی شبیهسازها/امولاتورها. (3) مقایسه عکسهای صفحه با baseline. (4) در صورت ناهماهنگی — تولید تصویر diff. (5) بارگذاری آرتفاکتهای diff (actual, expected, diff — سه فایل). (6) انتشار گزارش HTML با جدول نتایج. (7) اگر آستانه تجاوز شده باشد — تست مردود میشود. (8) بازبین آرتفاکتهای diff را بررسی کرده و تصمیم میگیرد: تایید (بهروزرسانی baseline) یا رد (ترمیم کد).
آستانه و تحمل — مقایسه مطلق پیکسل به پیکسل خیلی سختگیرانه است. از SSIM (Structural Similarity Index) یا MSE (Mean Squared Error) استفاده کنید. SSIM 0.98 = 98% تشابه ساختاری — آستانه مناسب. برای صفحات مختلف آستانههای مختلفی مورد نیاز است: حالت تیره (سیاه بیشتر — دقت بالاتر)، گرادیانها (نویز بیشتر — دقت پائینتر). آستانه را به صورت per-test از طریق پارامتر تنظیم کنید: @ScreenshotTest(threshold = 0.99).
Device Farm vs شبیهساز — آزمایش روی دستگاههای واقعی (Firebase Test Lab، AWS Device Farm) حداکثر واقعگرایی را ارائه میدهند اما کند و پرهزینه هستند. آزمایش روی شبیهسازها/امولاتورها — سریع و رایگان است، اما ویژگیهای دستگاه واقعی (مختلف GPU، ترگیب رنگ صفحه نمایش، تراکم پیکسل) را نشان نمیدهند. استراتژی: شبیهساز برای بررسی pre-merge (5 دقیقه)، Device Farm برای nightly (30 دقیقه، 20 دستگاه). در IT Sectr از Firebase Test Lab برای اجرای nightly روی برترین 10 دستگاه Android استفاده میکنیم.
سوالات متداول
Golden Test — برای بررسی سریع کامپوننتهای جداگانه UI در هر کامیت (50-200 میلیثانیه). Screenshot Test — برای بررسی E2E کامل صفحات روی دستگاههای واقعی قبل از انتشار (2-30 ثانیه). از هر دو استفاده کنید: golden برای کامپوننتهای Design System، screenshot برای مسیرهای حساس کاربر. نسبت 80/20 برای اکثر پروژهها بهینه است.
SSIM 0.98 — آستانه شروع مناسب برای اکثر صفحات. برای حالت تیره میتوانید 0.99 استفاده کنید (کنتراست بالاتر — مقایسه دقیقتر). برای صفحات با گرادیان و تصاویر — 0.95-0.97. از مقایسه مطلق پیکسل به پیکسل (MSE = 0) استفاده نکنید — به دلیل anti-aliasing و تفاوت GPU 20-30% موارد مثبت کاذب ایجاد میکند. آستانه را برای هر تست به صورت فردی تنظیم کنید.
با هر تغییر عمدی در UI — تغییر رنگها، فونتها، فاصلهها، آیکونها، افزودن/حذف عناصر. baseline را با تغییر محیط (نسخه OS، فونتهای در CI) بهروز نکنید — این نشانه تست flaky است. Baseline تنها محلی توسط توسعهدهنده پس از code review بهروز میشود: baseline قدیمی حذف، تستها با record=true اجرا، عکسهای جدید بررسی، کامیت.
بله — از طریق Espresso در Android و XCUITest در iOS. Espresso داخل پروسه اپلیکیشن کار میکند و نیازی به Accessibility Service (مانند UI Automator) ندارد. XCUITest — چارچوب استاندارد Apple برای تستهای UI. برای تستهای screenshot تفاوت اندک است: XCUITest کمی پایدارتر (API داخلی Apple)، UI Automator کمی انعطافپذیرتر (ارتباط بین پروسهای).
اگر به درستی تنظیم شده باشند — خیر. Pre-merge: تنها تستهای screenshot روی صفحات تغییر یافته را اجرا کنید (30-60 ثانیه). Nightly: اجرای کامل در Device Farm (30 دقیقه، 20 دستگاه). زمان اجرای تستهای screenshot روی امولاتور: 2-10 ثانیه در هر صفحه. 20 صفحه = 40-200 ثانیه. این از زمان تست دستی یک صفحه (5-10 دقیقه) کمتر است.
نتایج
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید