Тестирование рекламы в мобильной игре: rewarded, interstitial, медиация и edge-кейсы
В free-to-play игре реклама — это не «баннер внизу», а основной источник дохода и один из самых богатых на граничные случаи кусков продукта. Здесь QA отвечает на вопрос, который напрямую конвертируется в деньги и в отзывы в сторе: выдалась ли награда ровно один раз и не сломали ли мы игроку сессию неуместной рекламой.
Разберём, что и как тестировать в рекламной монетизации мобильной игры — по форматам, состояниям и медиации.
Форматы и что у каждого ломается
- Rewarded video — игрок смотрит ролик за награду. Главная зона риска (см. ниже).
- Interstitial — полноэкранная вставка между экранами. Риск — момент показа: не поверх загрузки, диалога, не во время геймплея.
- Banner — постоянный баннер. Риск — перекрытие UI, safe area, refresh, тапы по краю игрового поля.
- App-open — реклама на холодном/тёплом старте. Риск — показ поверх сплеша, при возврате из IAP-флоу, при deep link.
- Native / playable — встроенные форматы. Риск — вёрстка под разные экраны и клики.
Главный риск — награда (rewarded): ровно один раз
Награду игрок должен получить ровно один раз — не ноль, не дважды. Это идемпотентность на уровне продукта. Тест-кейсы:
- Ролик досмотрен полностью → награда выдана один раз.
- Рекламу закрыли на 2-й секунде (до порога награды) → награда НЕ выдана, прогресс не тронут.
- Свернули приложение во время ролика и вернулись → корректное состояние, без двойной награды.
- Пропала сеть в середине показа → награда не «застряла», UI не завис, игрок не наказан.
- Двойной callback от SDK (повторный
onRewarded) → награда не задваивается (дедуп по ad-instance). - Server-Side Verification (SSV): награда начисляется на сервере, а не только в клиенте — иначе тривиальный чит. Проверить подпись/валидацию колбэка.
- Убили приложение сразу после досмотра, до начисления → при следующем запуске награда либо доезжает, либо честно не выдана, без задвоения.
Если награда живёт только в клиенте — это не фича, это дыра. Rewarded-награда должна подтверждаться сервером (SSV).
No-fill и пустой инвентарь
Рекламы может не быть (нет подходящего объявления — no-fill). Это нормальное состояние, не ошибка. Что проверяем:
- Кнопка rewarded недоступна/в состоянии загрузки, а не «нажал — ничего не произошло».
- Прогресс игрока не блокируется отсутствием рекламы (нельзя запирать прохождение за ad, которого нет).
- Повторная загрузка (preload) после no-fill — без бесконечных ретраев, забивающих сеть и батарею.
- Interstitial при no-fill просто пропускается, игрок идёт дальше без зависания.
Медиация и waterfall
Доход вытягивает медиация: один SDK (например, AppLovin MAX или AdMob mediation) опрашивает несколько рекламных сетей по приоритету (waterfall) или через bidding. Что тестировать:
- Порядок сетей и таймауты: если сеть №1 молчит, переходим к №2, а не висим.
- Fallback до самого низа waterfall без падений и утечек.
- Тестовые объявления / test mode у каждой сети — чтобы не открутить себе реальные показы (это бан).
- Mediation debugger SDK: какие адаптеры подключены, какие версии, где ошибки инициализации.
- Разные гео/валюты, если eCPM и доступность сетей зависят от страны.
Момент показа: frequency capping, pacing, placement
- Frequency capping: не показываем interstitial чаще лимита (например, не чаще раза в N минут / уровней).
- Pacing: не два полноэкранных подряд, не interstitial сразу после rewarded.
- Placement: реклама не поверх загрузочного экрана, модального диалога, не во время активного геймплея, не на первых секундах первой сессии (FTUE).
- Контекст: не показываем interstitial перед/после критичных экранов (оплата, туториал), где это сломает воронку.
Consent: ATT и GDPR/UMP
Без согласия реклама всё равно грузится, но становится неперсонализированной. Что проверяем:
- iOS ATT (App Tracking Transparency): запрос показывается в правильный момент; при отказе IDFA недоступен, реклама non-personalized, приложение работает.
- GDPR / UMP (consent через UMP): форма согласия показана в EU; выбор пользователя пробрасывается во все сети медиации.
- Порядок: consent до инициализации/загрузки рекламы, иначе персонализация утечёт без согласия.
- Сброс согласия / смена региона → форма показывается снова, состояние консистентно.
Сеть и состояния устройства
- Офлайн и медленная сеть (троттлинг): реклама не грузится — деградируем мягко, без зависаний.
- Бэкграунд/возврат во время показа; входящий звонок; блокировка экрана.
- Ротация экрана и разные соотношения сторон: полноэкранная реклама не ломает вёрстку, баннер уважает safe area.
- Звук: реклама не орёт поверх mute-режима игры; возврат громкости после ролика.
- Холодный старт vs тёплый: app-open не дерётся со сплешем и deep link.
Аналитика и выручка
Реклама без корректной аналитики — это слепая монетизация. Проверяем, что события impression / click / reward / revenue отправляются и бьются между SDK сети, медиацией и продуктовой аналитикой. Импрешн-левел ревенью (ILRD/impression revenue) должен сходиться с отчётами сетей. Расхождение показов/выручки SDK vs аналитика — частый молчаливый баг.
Инструмент: живой трафик рекламных SDK удобно смотреть через перехват HTTP (Proxyman/Charles) — видно реальные запросы к сетям, consent-флаги, колбэки наград, а не только логи устройства.
Чек-лист тестирования рекламной монетизации (13 пунктов)
- Rewarded-награда выдаётся ровно один раз; закрытие до порога = нет награды.
- Награда подтверждается сервером (SSV), не живёт только в клиенте.
- Свернуть/убить приложение во время и после ролика — без задвоения и потери.
- No-fill — это валидное состояние: кнопка в loading/disabled, прогресс не заблокирован.
- Preload без бесконечных ретраев, не жрёт батарею и сеть.
- Waterfall/bidding: таймауты, fallback, порядок сетей работают, нет зависаний.
- Test mode включён у всех сетей в QA-сборках (никаких реальных показов).
- Frequency capping и pacing соблюдаются; нет двух полноэкранных подряд.
- Placement корректен: не поверх загрузки/диалога/геймплея/FTUE.
- ATT (iOS) и UMP/GDPR (EU): consent до загрузки, отказ не ломает приложение.
- Офлайн/медленная сеть/бэкграунд/звонок/ротация — мягкая деградация.
- Звук рекламы уважает mute; громкость восстанавливается.
- События impression/click/reward/revenue бьются между SDK, медиацией и аналитикой.
Итог
Реклама в игре — это идемпотентность награды + уместность показа + корректный consent + сходимость аналитики. Большинство дорогих багов здесь не «реклама не показалась», а «награда выдалась дважды», «прогресс заперт за no-fill» и «персонализация без согласия». Их ловит системный чек-лист по состояниям, а не разовый прогон «посмотрел ролик — получил монеты».