Понимание архитектур мобильных приложений
Прежде чем эффективно тестировать мобильное приложение, нужно понять, как оно было создано. Архитектура напрямую определяет, какие инструменты вы используете, какие типы багов ожидать и на чём сфокусировать усилия тестирования.
Существует три основных подхода к созданию мобильных приложений, каждый со своими последствиями для тестирования.
Нативные приложения
Нативные приложения создаются специально для одной платформы с использованием официального языка и SDK.
Характеристики
| Платформа | Язык | IDE | UI-фреймворк |
|---|---|---|---|
| iOS | Swift или Objective-C | Xcode | UIKit или SwiftUI |
| Android | Kotlin или Java | Android Studio | Jetpack Compose или XML Views |
Примеры: Apple Maps, Google Maps, большинство банковских приложений, Instagram (в основном нативный).
Последствия для тестирования
Преимущества для тестировщиков:
- Полный доступ к платформо-специфичным инструментам тестирования (XCUITest, Espresso)
- Предсказуемое поведение — следует гайдлайнам дизайна платформы
- Лучшая производительность — меньше багов, связанных с performance
- Прямой доступ ко всему оборудованию и API устройства
Вызовы для тестировщиков:
- Необходимы отдельные наборы тестов для iOS и Android
- Требуется знание обоих экосистем тестирования
- Два кодовых базы означают два источника багов
- Больший общий объём тестирования (2x платформы)
Инструменты нативного тестирования
Стек тестирования iOS:
XCTest → Unit-тесты
XCUITest → UI-автоматизация
Instruments → Профилирование производительности
Стек тестирования Android:
JUnit + Mockito → Unit-тесты
Espresso → UI-автоматизация (in-process)
UI Automator → UI-автоматизация (cross-process)
Android Profiler → Профилирование производительности
Гибридные приложения
Гибридные приложения оборачивают веб-технологии (HTML, CSS, JavaScript) в нативный контейнер с компонентом WebView.
Характеристики
| Аспект | Детали |
|---|---|
| Основная технология | HTML/CSS/JavaScript |
| Контейнер | Нативная оболочка с WebView |
| Фреймворки | Cordova, Ionic, PhoneGap |
| Доступ к устройству | Через плагины/мосты |
| Дистрибуция | App Store / Play Store |
Как работают гибридные приложения
┌─────────────────────────┐
│ Нативная оболочка │
│ ┌───────────────────┐ │
│ │ WebView │ │
│ │ ┌─────────────┐ │ │
│ │ │ HTML/CSS/JS │ │ │
│ │ │ (Ваше App) │ │ │
│ │ └─────────────┘ │ │
│ └───────────────────┘ │
│ ┌───────────────────┐ │
│ │ Нативные плагины │ │
│ │ (Камера, GPS...) │ │
│ └───────────────────┘ │
└─────────────────────────┘
Проблема WebView
Компонент WebView — крупнейший источник багов в гибридных приложениях:
- Android: WebView основан на Chrome, но поставляется отдельно и обновляется независимо
- iOS: WKWebView использует движок рендеринга Safari, более консистентный, но различается между версиями iOS
- Samsung: Браузер Samsung Internet может влиять на поведение WebView на устройствах Samsung
Кроссплатформенные приложения
Кроссплатформенные фреймворки позволяют писать код один раз и развёртывать на iOS и Android с более нативным опытом, чем гибридные приложения.
Основные фреймворки
| Фреймворк | Язык | Рендеринг | Компания |
|---|---|---|---|
| React Native | JavaScript/TypeScript | Нативные компоненты через мост | Meta |
| Flutter | Dart | Собственный движок (Skia/Impeller) | |
| Kotlin Multiplatform | Kotlin | Нативный UI на каждой платформе | JetBrains |
| .NET MAUI | C# | Нативные элементы управления | Microsoft |
React Native
React Native использует JavaScript-мост для связи с нативными компонентами UI:
JavaScript-поток ←→ Мост ←→ Нативный поток
(Ваш код) (JSON) (Рендеринг UI)
Flutter
Flutter использует принципиально другой подход — рендерит всё собственным движком:
Dart-код → Движок Skia/Impeller → Пиксели на экране
(Нативные UI-компоненты не используются)
Сравнение для тестировщиков
| Аспект | Нативные | Гибридные | React Native | Flutter |
|---|---|---|---|---|
| Производительность | Лучшая | Худшая | Хорошая | Очень хорошая |
| Доступ к API | Полный | Через плагины | Через модули | Через плагины |
| Консистентность UI | Нативная | Веб-подобная | Почти нативная | Попиксельно идентичная |
| Инструменты | Платформо-специфичные | Веб + мобильные | Detox, Appium | flutter_test, Appium |
| Отладка | Платформенные | DevTools + нативные | React DevTools + нативные | Flutter Inspector |
| Очаги багов | Edge case-ы платформы | Рендеринг WebView | Проблемы моста | Баги виджетов |
Стратегии тестирования по архитектуре
Стратегия для нативных приложений
Фокус на платформо-специфичном поведении:
- Отдельные планы тестирования для iOS и Android
- Платформо-специфичные UI-тесты на XCUITest (iOS) и Espresso (Android)
- Общие API-тесты, валидирующие поведение бэкенда
- Тестирование матрицы устройств, приоритизированное по аналитике пользователей
Стратегия для гибридных приложений
Фокус на консистентности WebView:
- Кросс-девайсное тестирование WebView — тестирование на разных версиях WebView
- Верификация плагинов — тестирование каждого нативного плагина на обеих платформах
- Тестирование производительности — гибридные приложения склонны к медлительности
- Офлайн-поведение — кэширование WebView может приводить к устаревшему контенту
- Тестирование сбоев моста — что происходит, когда вызов нативного плагина падает?
Стратегия для приложений React Native
Фокус на надёжности моста:
- Производительность моста — отслеживание потерянных кадров при интенсивном трафике
- Тестирование нативных модулей — платформо-специфичные модули требуют специфичных тестов
- Тестирование hot reload — проверка, что hot reload не маскирует проблемы
- Обнаружение утечек памяти — коммуникация через мост может приводить к утечкам
- Совместимость библиотек — экосистема React Native развивается быстро
Стратегия для приложений Flutter
Фокус на рендеринге виджетов:
- Тестирование виджетов — встроенный фреймворк тестирования Flutter
- Тестирование platform channels — проверка связи между Dart и нативным кодом
- Тестирование доступности — Flutter требует явных аннотаций semantics
- Golden image тестирование — сравнение UI с эталонными скриншотами
- Performance overlay — мониторинг производительности рендеринга
Упражнение: Определите архитектуру
Для каждого описания определите наиболее вероятную архитектуру и назовите две проблемы тестирования.
- Банковское приложение с Face ID на iOS и отпечатком пальца на Android, с платформо-специфичными анимациями и скроллингом 60fps
- Внутренний корпоративный справочник с профилями сотрудников, созданный за 3 месяца командой веб-разработчиков
- Приложение соцсети, где лента выглядит идентично на iOS и Android, с плавными анимациями и кастомными UI-компонентами
Решение
Нативное приложение — интеграция Face ID/отпечатка, платформо-специфичные анимации и высокая производительность. Проблемы: (a) Отдельные наборы тестов для каждой платформы; (b) Тестирование биометрии требует физических устройств.
Гибридное приложение (Cordova/Ionic) — короткие сроки, команда веб-разработчиков, внутренний инструмент. Проблемы: (a) Различия рендеринга WebView; (b) Совместимость плагинов.
Flutter-приложение — попиксельно идентичный UI с кастомными компонентами. Проблемы: (a) Доступность требует явных аннотаций semantics; (b) Кастомные виджеты нуждаются в визуальном регрессионном тестировании.
Советы из продакшен-опыта
Совет 1: Всегда проверяйте реальную архитектуру. Разработчики могут сказать, что приложение на React Native, но некоторые экраны могут быть нативными ради производительности.
Совет 2: Кроссплатформенность не означает «тестируем один раз». Даже Flutter по-разному взаимодействует с каждой ОС для разрешений, уведомлений, deep links и фоновой обработки.
Совет 3: Следите за циклами обновлений. Кроссплатформенные фреймворки обновляются часто. Включайте тестирование обновлений фреймворка в стратегию регрессии.
Ключевые выводы
- Нативные приложения обеспечивают лучшую производительность и доступ к устройству, но требуют отдельных кодовых баз и наборов тестов
- Гибридные приложения разделяют код, но страдают от несогласованности WebView
- React Native связывает JavaScript с нативными компонентами — следите за багами моста
- Flutter рендерит независимо от нативного UI — фокусируйтесь на тестировании виджетов и доступности
- Архитектура приложения напрямую определяет инструменты, стратегию и фокус тестирования