Мобильная разработка
Unit и UI Testing
Релиз в App Store каждые 2 недели. Ручное регрессионное тестирование занимает 3 дня QA команды. Автоматизация сокращает его до 30 минут CI. Но написать плохие тесты хуже чем не писать совсем: flaky E2E тесты блокируют релизы чаще, чем сами баги.
- Airbnb: пирамида тестов iOS приложения - 2000+ unit тестов (секунды), 200 UI тестов (минуты), 50 E2E тестов (часы на CI)
- Wix (создатель Detox): 600+ Detox E2E тестов, параллельный запуск на 20 симуляторах в CI, 40 минут full suite
- Google Android команда: Espresso тесты как gate для code review - PR не мерджится без прохождения UI тестов
XCTest: тестирование iOS приложений
XCTest - Apple's встроенный фреймворк для unit и UI тестов. Запускается в Xcode или командной строке через xcodebuild. Unit тесты выполняются без симулятора (быстро), UI тесты - с симулятором через XCUITest. XCTest Expectation решает проблему async тестирования.
XCTest Performance: measure { } блок измеряет время выполнения и сравнивает с baseline. Используется для performance regression testing. Instruments profiling + XCTest: стандартный workflow для обнаружения утечек памяти и CPU spike в тестовой среде.
Чем XCUITest отличается от XCTest unit тестов по скорости выполнения?
Espresso: UI тестирование Android
Espresso - Google's Android UI testing framework. Автоматически синхронизируется с UI thread - нет sleep() хаков. Архитектура: ViewMatcher (найти элемент), ViewAction (выполнить действие), ViewAssertion (проверить состояние). IdlingResource для async операций.
Espresso IdlingResource: регистрация async операций, которые Espresso должен дождаться. Без IdlingResource тест может проверить состояние до завершения сетевого запроса. OkHttp IdlingResource, Coroutine IdlingResource - готовые реализации для популярных библиотек.
Почему Espresso не требует Thread.sleep() между действиями как многие другие UI фреймворки?
Snapshot Testing: визуальная регрессия
Snapshot тест делает скриншот UI компонента, сохраняет как эталон. Последующие запуски сравнивают с эталоном пиксель-в-пиксель. Любое изменение верстки - failure. Polished: быстро ловит регрессии верстки; проблема: flaky тесты при разных устройствах/шрифтах.
Главный недостаток snapshot тестирования в мобильных приложениях:
Detox: E2E тестирование React Native
Detox - E2E тестирование React Native от Wix. В отличие от WebDriver-based инструментов, Detox работает внутри процесса приложения, что даёт детерминизм: синхронизация с JS event loop, нет случайных timeouts. Тесты пишутся на JavaScript/TypeScript.
Тестовая пирамида для мобильных: 70% unit тесты (XCTest/JUnit, быстро), 20% integration (Espresso/XCUITest), 10% E2E (Detox/Appium). E2E тесты дорогие по времени CI: Detox на симуляторе - 2-5 минут за тест suite. Параллельный запуск на нескольких симуляторах в CircleCI/Bitrise.
Почему Detox детерминированнее WebDriver-based инструментов для React Native?
Ключевые идеи
- XCTest/Espresso: unit тесты быстрые (без устройства), UI тесты медленные (симулятор) - строго разделять.
- Snapshot testing: быстрая визуальная регрессия, но flaky при разных устройствах - использовать с фиксированным simulator.
- Тестовая пирамида: 70% unit, 20% integration, 10% E2E - E2E дороги, используются для критических flows.
Связанные темы
Тестирование - часть полного мобильного CI/CD pipeline:
- Mobile CI/CD и Release — Fastlane scan запускает XCTest/Espresso в CI pipeline - тесты как gate перед релизом
- Mobile Architecture at Scale — Хорошая архитектура (Clean Architecture, MVI) делает unit тестирование возможным - изолированные компоненты легко тестировать
Вопросы для размышления
- Где граница между unit и integration тестом в мобильном приложении: тест ViewModel с mock Repository - это что?
- Как snapshot тесты интегрировать в code review процесс так, чтобы они помогали, а не мешали?
- Когда имеет смысл отказаться от E2E тестов в пользу более быстрых integration тестов?