Оплата проверена вдоль и поперёк: карта, промокод, чек. У пользователя посреди ввода карты звонит телефон. Через минуту он возвращается — корзина пуста, промокод слетел, приложение открылось с главного экрана. Функция работает, оплаты нет.
Телефон отличается от браузера не размером экрана — про вёрстку и наборы экранов есть отдельная статья. Здесь про другое: экраном, памятью, сетью и доступом к камере на телефоне распоряжается система, и она в любой момент отодвигает приложение в сторону или выгружает совсем.
Четвёртый шаг — не редкость, а обычное поведение системы при нехватке памяти. Если приложение не сохранило состояние экрана, возврат из фона выглядит как сброс: введённое пропало, шаг формы забыт, а таймер брони мог тем временем истечь. Для пользователя все четыре шага — одно действие: «свернул и вернулся».
Нативное, гибридное, веб и PWA
«Мобильное приложение» — четыре разные вещи, и от того, какая перед вами, зависит, где искать причину.
Нативное написано под одну систему (Kotlin или Java для Android, Swift для iOS) и ставится из магазина. Гибридное — веб-страница внутри окна-обёртки: кнопки выглядят родными, а нарисованы HTML и CSS, поэтому половина дефектов тут веб-дефекты, а половина — на стыке обёртки с камерой и уведомлениями. Мобильный сайт живёт в браузере телефона и обновляется мгновенно. PWA — тот же сайт на домашнем экране: свой значок, запуск без адресной строки, часть данных доступна без сети.
Для проверок разница в трёх вещах: как доезжает новая версия (магазин с проверкой и раскаткой — или обновление страницы у всех сразу), где логи (журнал системы — или консоль браузера), что доступно из системы (камера, отпечаток, уведомления, файлы — у веб-версии набор урезан).
Прерывания: то, что проверяют первым
Звонок, будильник, уведомление, кнопка «домой», карта поверх — экран уходит в фон и через минуту возвращается. Иногда не тем же: системе не хватило памяти, и фоновый процесс она выгрузила.
Проверяют это первым, потому что ломается почти всё: черновик, таймер брони, видео, играющее поверх звонка, платёж, ушедший вторым запросом.
Набор одинаков для любого приложения: свернуть на середине формы и вернуться; принять звонок; открыть шторку; повернуть экран; заблокировать и разблокировать; закрыть приложение из списка задач и открыть заново.
Ждать выгрузку бессмысленно: в меню разработчика Android есть переключатель «Не сохранять действия» (Don't keep activities) — система убивает экран сразу, как он ушёл в фон, и потеря состояния находится за минуту.
Сеть: переключения и офлайн
На стенде Wi-Fi ровный, у пользователя — метро, лифт и переход с домашнего Wi-Fi на мобильную сеть у подъезда. Сеть на телефоне не делится на «есть» и «нет»: она бывает медленной и обрывается посреди загрузки.
Что проверяют: авиарежим на середине отправки — приложение говорит, что связи нет, не показывает пустой экран и не теряет введённое; вернуть сеть — данные догружаются сами или по кнопке, без перезахода; переключить Wi-Fi на мобильную сеть прямо во время запроса; открыть приложение на медленном канале — профили скорости есть в эмуляторе и в DevTools.
Главная ловушка — повтор: запрос ушёл, сервер его выполнил, ответ не доехал, приложение отправило ещё раз — и появился второй заказ. Проверка: оборвать сеть сразу после «Оплатить», вернуть и посмотреть, сколько заказов и списаний получилось.
Разрешения: выдали, отказали, отозвали
Камеру, геолокацию, уведомления, контакты и файлы приложение получает у системы, и пользователь в любой момент может передумать. Состояний три, проверяют обычно одно.
Выдали — обычный путь. Отказали — приложение обязано остаться рабочим: объяснить, зачем нужно разрешение, и оставить обходной путь (адрес руками вместо геолокации). Отозвали позже, в настройках системы, — самый ломкий случай: Android при отзыве убивает процесс, и приложение стартует заново. Отдельно проверяют «отказать и больше не спрашивать»: системный диалог не появится никогда, и вести в настройки приложение должно само.
Установка, обновление и версия
Чистая установка и обновление поверх — два разных сценария, и ломается обычно второй: у пользователя уже лежат данные прошлой версии, вход и кэш, и новая сборка должна их пережить.
Порядок: поставить прошлую версию, войти, создать данные, обновиться на новую сборку. Вход остался, данные открылись, экраны не падают.
У сборки два номера: тот, что видит пользователь (3.4.1), и внутренний, растущий с каждой сборкой. В дефект пишут оба плюс модель телефона и версию системы, иначе воспроизвести нечем. Магазин отдаёт версию не всем сразу: «у меня обновилось, у тебя нет» — норма, а не дефект.
Глубокие ссылки и уведомления
Глубокая ссылка открывает не главный экран, а конкретный: письмо про заказ — сразу к заказу. Проверяют в трёх состояниях: открыто, свёрнуто, закрыто. Ломается чаще всего третье — приложение стартует с нуля и теряет ссылку по дороге. Ещё два: пользователь не вошёл (после входа должен попасть на нужный экран, а не на главную) и объект удалён (понятное сообщение вместо пустоты).
С уведомлениями состояния те же три: открыто — уведомление не перекрывает работу; свёрнуто — приходит в шторку; закрыто — тап поднимает приложение и открывает нужный экран. Плюс мелочи: обрезка длинного текста, несколько уведомлений подряд, счётчик на значке, выключенные уведомления в настройках.
На чём проверять: устройства, эмуляторы, фермы
Моделей телефонов тысячи, версий системы — десятки, и поверх идут оболочки производителей, которые экономят батарею и убивают фоновые задачи по-своему. Набор собирают по статистике аудитории; обычно хватает четырёх-пяти устройств: самая массовая модель, самая старая поддерживаемая версия системы, самый маленький экран, один iPhone и один Android.
Эмулятор Android запускает настоящий образ системы на компьютере. Симулятор iOS — не телефон, а сборка приложения под macOS: память и скорость там свои, часть возможностей недоступна. Ни тот ни другой не дадут реальную камеру, отпечаток, слабый процессор, разряд батареи и настоящую мобильную сеть. Поэтому экраны гоняют на эмуляторе, а деньги, камеру, сеть и прерывания — на живом устройстве. Нет нужной модели — берут облачную ферму: настоящие телефоны в аренду по минутам, с удалённым экраном и логами.
Где смотреть логи
«Упало» без логов — не дефект, а сообщение о невезении. На Android журнал читают через adb: adb devices покажет подключённый телефон, adb logcat — поток системного журнала (в Android Studio это вкладка LogCat с фильтром по приложению), adb install app.apk поставит сборку, adb shell pm clear <пакет> сотрёт данные до состояния чистой установки. На iOS то же смотрят в Console на Mac или в окне устройств Xcode. Стек падения в баг-репорте экономит разработчику день поисков.
Коротко
- Приложением на телефоне распоряжается система: сворачивает, выгружает, отбирает разрешения.
- Прерывания проверяют первыми; выгрузку воспроизводит переключатель «Не сохранять действия» в меню разработчика Android.
- Сеть переключается и пропадает посреди запроса; главная ловушка — повтор, создающий второй заказ.
- У разрешения три состояния: выдали, отказали, отозвали позже — при отзыве Android перезапускает приложение.
- Обновление поверх — отдельный сценарий: данные, вход и кэш должны пережить новую сборку.
- Эмулятор и симулятор годятся для экранов; деньги, камеру, сеть и прерывания — на живом устройстве или в ферме.
Что почитать дальше
- Кроссбраузерное и мобильное тестирование — размеры экранов и адаптивность вёрстки.
- Основы сетей — что происходит, когда запрос не доехал до сервера.
- Как писать баг-репорт — что обязательно указать про телефон, сборку и систему.
- Мобильная разработка: web-first, гибрид или натив — та же развилка глазами разработки.