Реализация Debug Menu (скрытое меню) для тестировщиков мобильного приложения
Тестировщик хочет сбросить onboarding без переустановки приложения. Переключиться на staging. Принудительно вызвать push-уведомление. Посмотреть текущий feature flag state. Симулировать ошибку сети. Всё это — задачи для Debug Menu: скрытого экрана, доступного только в нужных сборках.
Архитектура Debug Menu
Debug Menu — отдельный экран (или набор экранов), доступный через скрытый gesture или специальную точку входа. Вызов: shake gesture, долгое нажатие на версию в Settings, секретный tap pattern на логотипе (5 тапов).
Принципиально важно: Debug Menu должен быть полностью исключён из release-сборки. Не скрыт, не за флагом — именно исключён из компиляции.
iOS — условная компиляция:
#if DEBUG || BETA
import UIKit
final class DebugMenuViewController: UIViewController {
// весь код debug menu
}
#endif
Android — отдельный build flavor:
app/
src/
main/
debug/
kotlin/com/example/debug/DebugMenuActivity.kt
release/
// DebugMenuActivity отсутствует
В debug/AndroidManifest.xml регистрируем DebugMenuActivity. В release-манифесте её нет. Gradle автоматически включает нужные sources по flavor.
Полезные функции Debug Menu
Environment switcher. Самая нужная функция: переключение между Dev/Staging/Production без пересборки. Реализация — UserDefaults/SharedPreferences с текущим environment, URLSessionConfiguration.default.protocolClasses или OkHttp interceptor читает его при каждом запросе. После переключения — принудительный logout и перезапуск сессии.
Управление feature flags. Если используется Firebase Remote Config или кастомная система флагов, Debug Menu позволяет локально переопределить значение флага. На Firebase это remoteConfig.setDefaults([key: value]) — локальные defaults перекрывают удалённые значения.
Сброс состояния. Кнопки: «Сбросить onboarding», «Очистить кеш», «Сбросить UserDefaults», «Удалить Keychain». Это ускоряет тестирование first-run флоу в 10 раз.
Инструменты для QA. Отображение текущего userId, device token (для push), версии API, environment-переменных. Кнопка «Скопировать device token» — тестировщик сразу может послать тестовый push через Firebase Console.
Симуляция ошибок. Checkbox «Network error mode» — OkHttp/URLSession interceptor начинает возвращать ошибки для всех запросов. Проверяем, как приложение обрабатывает offline-состояние без отключения Wi-Fi.
Пример структуры
DebugMenuScreen
├── Environment
│ ├── ● Dev (https://api-dev.example.com)
│ ○ Staging
│ ○ Production
├── Feature Flags
│ ├── new_checkout: [Remote] ON [Override] OFF ↺
│ └── ai_search: [Remote] OFF [Override] ON ↺
├── User
│ ├── User ID: abc-123 [Copy]
│ ├── Push Token: def-456 [Copy]
│ └── [Clear session]
├── Cache
│ ├── [Clear image cache] 482 MB
│ └── [Clear all caches]
└── Simulate
├── [Trigger push notification]
├── [Force network error]
└── [Crash app] ← для тестирования Crashlytics
Доступ и безопасность
Если Debug Menu нужен в beta-сборках (TestFlight/Firebase App Distribution), но не в release — используем отдельную build configuration: Debug, Beta, Release. В Beta конфигурации компилируем Debug Menu, но включаем pinning и другие production security меры. Так тестировщик работает с почти-production конфигурацией, но с удобствами отладки.
Никогда не оставляйте Debug Menu доступным через runtime-флаг в release (например, if BuildConfig.VERSION_NAME.contains("beta")). Это обходится элементарно.
Сроки
Базовый Debug Menu с environment switcher, управлением флагами и сбросом состояния — 2–3 дня. Расширенный с симуляцией ошибок и custom tools — ближе к 4 дням.







