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

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

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

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

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

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

Snapshot-тестирование — это автоматический контроль того, что UI не изменился незапланированно. Разработчик правит отступ в одном компоненте, забывает про экран настроек, где тот же компонент используется с другими пропсами — и через неделю в продакшене обнаруживается съехавшая вёрстка. Snapshot-тест поймал бы это за секунды.

Суть проста: при первом запуске тест сохраняет эталонное изображение или сериализованное дерево компонентов. При каждом следующем запуске сравнивает с эталоном. Расхождение = падающий тест.

iOS: iOSSnapshotTestCase

На iOS snapshot-тесты строятся на FBSnapshotTestCase (Facebook, переехал в pointfreeco/swift-snapshot-testing) или нативном XCTAttachment + ручное сравнение. Наиболее зрелое решение — pointfreeco/swift-snapshot-testing:

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() } — та же механика.

Главное преимущество перед screenshot-тестами с эмулятором: скорость. Paparazzi-тест выполняется за 200–500 мс против 5–10 секунд на эмуляторе. Для библиотеки на 200 компонентов разница в 30 минут vs 3 минуты.

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(), который нивелирует часть различий.

Управление базовыми снимками в 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+ компонентов) — оцениваем отдельно. Стоимость рассчитывается индивидуально.