Screenshot Test — автоматизована перевірка користувацького інтерфейсу шляхом захоплення та порівняння скріншотів екранів додатка з еталонними зображеннями. На відміну від golden-тестів, screenshot-тести виконуються на реальних пристроях або емуляторах, захоплюють повні екрани з навігацією, системними елементами та анімаціями, і використовують UI Automator (Android) або XCUITest (iOS) для взаємодії з додатком. Докладніше — у документації Android UI Automator.
Головне
Screenshot Test — це наскрізне тестування користувацького інтерфейсу, під час якого тест відкриває екран додатка, виконує дії (тапи, введення тексту, скрол) і робить скріншот отриманого стану. Скріншот порівнюється з еталоном (baseline), що зберігається в репозиторії. Якщо скріншоти відрізняються — тест падає. Screenshot-тести виявляють візуальні регресії, які не видно unit-тестам: неправильні відступи, накладання елементів, невірні кольори.
Навіщо потрібні screenshot-тести, якщо є golden-тести — golden-тести перевіряють компоненти ізольовано: одна кнопка, одна картка, один текст. Screenshot-тести перевіряють цілий екран у середовищі, максимально наближеному до продакшену: реальна навігація, реальні дані (або максимально реалістичні моки), реальні системні шрифти, реальний статус-бар. Тільки screenshot-тест покаже, що кнопка перекривається іншим елементом на реальному пристрої.
Бізнес-цінність — за даними Google (2023), візуальні баги становлять 15-25% всіх багів мобільних додатків. Screenshot-тести автоматизують перевірку візуальної якості, яка раніше робилася вручну QA-інженерами. Один screenshot-тест замінює 5-10 хвилин ручного тестування одного екрана. Для додатка з 50 екранами економія: 4-8 людино-годин на один регресійний прогін. Screenshot-тести окупаються за 2-3 релізних цикли.
Golden-тести швидші та простіші: рендер компонента в off-screen buffer займає мілісекунди, не потребує пристрою, стабільні на 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 інтегрується з CI через gcloud CLI або Gradle plugin.
Shot — бібліотека для screenshot-тестування на Android, що полегшує створення та порівняння скріншотів. Shot працює поверх Espresso та UI Automator, додаючи manage golden (створення, оновлення, видалення), порівняння з threshold (пікселі або відсотки) та генерацію 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.
Comparison frameworks — iOSSnapshotTestCase (Uber) працює і для screenshot-тестів, якщо запускати на симуляторі. SwiftSnapshotTesting (pointfree) більше орієнтований на golden-тести компонентів. Для screenshot-тестів на iOS використовуйте вбудовані засоби XCUITest + XCTAttachment + кастомний ImageComparator (Pixelmator або AImage). На CI використовуйте simulator — на реальних пристроях screenshot-тести працюють тільки через Device Farm (AWS Device Farm).
Baseline management — еталонні скріншоти зберігаються в репозиторії (Git LFS) або в S3. Кожен скріншот іменується за шаблоном: {testName}_{device}_{orientation}_{locale}.png. Приклад: loginScreenPixel7PortraitRu.png. При додаванні нового пристрою або локалі створюється новий baseline. При зміні UI старі baseline замінюються новими після code review. Baseline — це частина кодової бази, як і вихідні коди тестів.
CI Pipeline — (1) Збірка додатка. (2) Запуск screenshot-тестів на емуляторах/симуляторах. (3) Порівняння скріншотів з baseline. (4) При неспівпадінні — генерація diff-зображення. (5) Завантаження diff-артефактів (actual, expected, diff — три файли). (6) Публікація HTML-звіту з таблицею результатів. (7) Якщо threshold перевищено — тест падає. (8) Reviewer переглядає diff-артефакти та приймає рішення: approve (оновити baseline) або reject (фіксити код).
Threshold та tolerance — абсолютне попіксельне порівняння занадто суворе. Використовуйте SSIM (Structural Similarity Index) або MSE (Mean Squared Error). SSIM 0.98 = 98% структурної схожості — хороший поріг. Для різних екранів можуть знадобитися різні threshold: темна тема (більше чорного — вища точність), градієнти (більше шуму — нижча точність). Налаштовуйте threshold per-test через параметр: @ScreenshotTest(threshold = 0.99).
Device Farm vs Simulator — тести на реальних пристроях (Firebase Test Lab, AWS Device Farm) дають максимальну реалістичність, але повільні та платні. Тести на симуляторах/емуляторах — швидкі та безкоштовні, але не показують real-device особливості (різні GPU, кольоропередача дисплея, щільність пікселів). Стратегія: simulator для pre-merge перевірки (5 хвилин), Device Farm для nightly (30 хвилин, 20 пристроїв). В IT Sectr використовуємо Firebase Test Lab для нічних прогонів на топ-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) — воно дає 20-30% хибних спрацьовувань через anti-aliasing та різницю GPU. Налаштовуйте threshold індивідуально під кожен тест.
При кожному навмисному зміненні UI — зміні кольорів, шрифтів, відступів, іконок, додаванні/видаленні елементів. Не оновлюйте baseline при зміні оточення (версія ОС, шрифти на CI) — це ознака flaky test. Baseline оновлюється тільки локально розробником після code review: видалив старі baseline, запустив тести з record=true, перевірив нові скріншоти, закомітив.
Так — через Espresso на Android та XCUITest на iOS. Espresso працює всередині процесу додатка і не потребує Accessibility Service (як UI Automator). XCUITest — стандартний фреймворк Apple для UI-тестів. Для screenshot-тестів різниця мінімальна: XCUITest трохи стабільніший (рідний Apple API), UI Automator трохи гнучкіший (міжпроцесна взаємодія).
Якщо налаштовані правильно — ні. Pre-merge: запускайте тільки screenshot-тести на змінених екранах (30-60 секунд). Nightly: повний прогін на Device Farm (30 хвилин, 20 пристроїв). Час виконання screenshot-тестів на емуляторі: 2-10 секунд на екран. 20 екранів = 40-200 секунд. Це менше, ніж час ручного тестування одного екрана (5-10 хвилин).
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також