Впровадження Snapshot-тестів для мобільного застосунку

Snapshot-тестування — це автоматичний контроль того, що UI не змінився незаплановано. Розробник править відступ в одному компоненті, забуває про екран налаштувань, де той самий компонент використовується з іншими пропсами — і через тиждень у продакшені виявляється з'їхавша верстка. Snapshot-тест зло

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Впровадження Snapshot-тестів для мобільного застосунку
Середній
~2-3 дні

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Snapshot-тестування — це автоматичний контроль того, що UI не змінився незаплановано. Розробник править відступ в одному компоненті, забуває про екран налаштувань, де той самий компонент використовується з іншими пропсами — і через тиждень у продакшені виявляється з'їхавша верстка. Snapshot-тест зловив би це за секунди. Ми впроваджуємо такі тести під ключ: налаштовуємо інструмент, пишемо тести для ключових компонентів та інтегруємо перевірку в CI. Це економить години ручних перевірок та запобігає регресіям.

Чому snapshot-тести критичні для мобільного застосунку?

Без автоматичної верифікації UI будь-яка зміна стилів або компонентів може призвести до візуальних багів, які не ловляться модульними тестами. Ручний перегляд екранів перед релізом — повільний і ненадійний. Snapshot-тести вирішують проблему: один запуск — 100% перевірка всіх екранів.

Суть проста: при першому запуску тест зберігає еталонне зображення або серіалізоване дерево компонентів. При кожному наступному запуску порівнює з еталоном. Розбіжність = падаючий тест.

Порівняння інструментів snapshot-тестування

Платформа Інструмент Середній час тесту Підтримка Compose/SwiftUI
iOS swift-snapshot-testing 1–3 сек SwiftUI (через UIView)
Android Paparazzi 200–500 мс Jetpack Compose
Flutter Golden Tests 0.5–1 сек Flutter Widget

Paparazzi в 20 разів швидше, ніж screenshot-тести з емулятором: 200 мс проти 6 секунд на тест. Для бібліотеки на 200 компонентів різниця 30 хвилин проти 3 хвилин.

iOS: iOSSnapshotTestCase

На iOS snapshot-тести будуються на pointfreeco/swift-snapshot-testing (колишній FBSnapshotTestCase). Це найбільш зріле рішення:

import SnapshotTesting class ProfileViewControllerTests: XCTestCase { func testProfileScreen() { let vc = ProfileViewController(user: .mock) assertSnapshot(of: vc, as: .image(on: .iPhone13Pro)) } func testProfileScreenDarkMode() { let vc = ProfileViewController(user: .mock) assertSnapshot(of: vc, as: .image(on: .iPhone13Pro(.landscape), traits: .init(userInterfaceStyle: .dark))) } } 

assertSnapshot при першому запуску створює файл __Snapshots__/ProfileViewControllerTests/testProfileScreen.1.png. При наступних — порівнює піксель за пікселем. Поріг — 0, будь-яке відхилення = fail.

Підтримувані стратегії знімка: .image (скріншот), .recursiveDescription (текстове дерево view), .dump (структура). Для компонент-бібліотек .image — основна.

Проблема зі шрифтами в CI

Рендеринг тексту на симуляторі може відрізнятися від рендерингу на CI-машині через різні версії системних шрифтів. Рішення — фіксувати симулятор (iPhone 15, iOS 17.4) і використовувати одну й ту саму версію Xcode. У fastlane через xcversion:

xcversion(version: "~> 15.3") 

Android: Paparazzi

Для Android найкращий інструмент — Paparazzi від Square. Він не потребує емулятора: рендерить View через LayoutInflater у JVM-середовищі, використовуючи layoutlib (той самий двигун, що й Android Studio Preview).

class ButtonSnapshotTest { @get:Rule val paparazzi = Paparazzi( deviceConfig = DeviceConfig.PIXEL_6, theme = "Theme.App" ) @Test fun primaryButton() { paparazzi.snapshot { PrimaryButton( text = "Зберегти", onClick = {} ) } } } 

Запуск: ./gradlew recordPaparazziDebug (запис еталонів) та ./gradlew verifyPaparazziDebug (перевірка).

Paparazzi підтримує Jetpack Compose з paparazzi.snapshot { ComposableFunction() } — та сама механіка.

Flutter: Golden Tests

У Flutter snapshot-тести називаються Golden Tests і є частиною flutter_test:

testWidgets('CustomCard golden', (tester) async { await tester.pumpWidget( MaterialApp(home: CustomCard(title: 'Test', subtitle: 'Subtitle')), ); await expectLater( find.byType(CustomCard), matchesGoldenFile('goldens/custom_card.png'), ); }); 

Оновлення еталонів: flutter test --update-goldens.

Платформозалежність golden-файлів — відома проблема. macOS рендерить шрифт інакше, ніж Linux (CI). Рішення: зберігати golden-файли, згенеровані на CI (Linux), а локально розробники використовують flutter test --update-goldens лише на тій самій ОС. Або пакет golden_toolkit з loadAppFonts(), який нівелює частину відмінностей.

Як snapshot-тести інтегруються в CI?

Ми налаштовуємо CI-пайплайн так, щоб у ньому виконувалася лише верифікація (verify), а запис еталонів відбувався локально. Це гарантує, що зміни UI не прослизнуть непоміченими.

Типові причини розбіжностей на CI
  • Різні версії шрифтів
  • Різний рендеринг на симуляторі та CI-машині
  • Роздільна здатність екрану та масштаб
  • Версії Xcode та SDK

Рекомендується фіксувати середовище та запускати запис еталонів на тому самому середовищі, де буде CI.

Приклад з нашої практики

Для одного з проектів (клієнт — fintech-сервіс) ми впровадили snapshot-тести на Flutter. Компонентна бібліотека містила 120 віджетів. Після налаштування golden-тестів час регресійного тестування UI скоротився з 2 годин ручного перегляду до 3 хвилин автоматичної перевірки. Всі еталонні знімки зберігаються в репозиторії та оновлюються лише усвідомлено.

Що входить в роботу

  • Аналіз поточної UI-архітектури та вибір інструменту
  • Налаштування інструменту snapshot-тестування (iOS/Android/Flutter)
  • Написання тестів для ключових екранів та компонентів (10–30 тестів)
  • Інтеграція в CI (GitHub Actions, GitLab CI або Bitrise)
  • Документація з роботи зі знімками та процесу оновлення
  • Навчання команди (1–2 години)

Управління базовими знімками в git

Еталонні знімки зберігаються в репозиторії. Кілька правил:

  • __Snapshots__/, src/test/snapshots/, test/goldens/ — додаємо в .gitattributes як бінарні: *.png binary
  • Pull Request зі зміною UI повинен включати оновлені знімки: git add test/goldens/ && git commit -m "update snapshots"
  • У CI запускаємо лише перевірку (verify), не запис (record). Запис — лише локально або через спеціальний workflow

Якщо CI падає через розбіжність знімків — це не помилка тестів, це сигнал про незаплановану зміну UI. Добре.

Строки та вартість

2–3 дні — налаштування інструменту + написання snapshot-тестів для ключових компонентів. Повне покриття компонентної бібліотеки (50+ компонентів) — оцінюємо окремо. Вартість розраховується індивідуально. У нас 5 років досвіду в мобільній розробці та понад 30 проектів з автотестами — гарантуємо якість та дотримання строків.

Замовте впровадження snapshot-тестів вже сьогодні — отримайте консультацію по вашому проекту. Зв'яжіться з нами для оцінки — ми підберемо оптимальний інструмент та складемо план впровадження.