Screenshot Test — автоматизирана проверка на потребителския интерфейс чрез заемане и сравнение на екранни снимки на приложението с референтни изображения. За разлика от golden тестовете, screenshot тестовете се изпълняват на реални устройства или емулатори, заемат цели екрани с навигация, системни елементи и анимации, и използват UI Automator (Android) или XCUITest (iOS) за взаимодействие с приложението. Повече — в документацията на Android UI Automator.
Основни неща
Screenshot Test — това е end-to-end тестване на потребителския интерфейс, при което тестът отваря екрана на приложението, извършва действия (допиране, въвеждане на текст, превъртане) и прави екранен снимка на полученото състояние. Екранният снимка се сравнява с референция (baseline), съхранявана в репозиторията. Ако екранните снимки се различават — тестът се проваля. Screenshot тестовете откриват визуални регресии, които не са видими в единичните тестове: неправилни полета, припокриване на елементи, грешни цветове.
Защо са нужни screenshot тестовете, ако има golden тестове — golden тестовете проверяват компонентите изолирано: един бутон, една карта, един текст. Screenshot тестовете проверяват целия екран в среда, максимално близка до производствената: реална навигация, реални данни (или максимално реалистични mockове), реални системни шрифтове, реална лента за състояние. Само 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 тестовете — за критични потребителски пътища: onboarding, влизане, платежен поток, количка. 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.
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.
Framework-за сравнение — 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 за нощни пробези на топ 10 Android устройства.
Често задавани въпроси
Golden Test — за бърза проверка на отделни UI компоненти при всяко комитване (50-200 ms). 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. Настройте прага индивидуално за всяка проба.
При всяка преднамерена промяна на 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 създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също