Тестирование SMS-подтверждения требует разных инструментов. Мок подходит для быстрой проверки логики, тестовые номера платформы — для CI, а реальный номер оператора нужен, когда важно проверить доставку OTP, фильтры типа линии и региональные правила. Одного подхода для всех этапов нет.
Ниже собрана рабочая схема для разработчиков и QA: какой номер выбрать, как разделить dev, staging и production, как подключить получение кода к тест-раннеру и какие ошибки нельзя пропускать.
Как выбрать способ тестирования SMS
Сначала определите, что именно проверяется. Для валидации поля телефона не нужна доставка сообщения. Для проверки генерации и срока жизни кода не нужен внешний оператор. Реальный номер понадобится только там, где тест проходит через инфраструктуру сервиса и настоящую SMS-маршрутизацию.
- Мок SMS-слоя. Подходит для unit-тестов: код отправляется в тестовую базу или кэш, а внешний провайдер не вызывается.
- Тестовые номера платформы. Firebase, Twilio и AWS предлагают режимы, где заданный номер получает фиксированный код или возвращает предсказуемый ответ. Это удобный вариант для CI/CD.
- Временный публичный номер. Подходит для ручной разовой проверки. Входящие сообщения видны другим посетителям, поэтому такой номер нельзя связывать с чувствительной учётной записью.
- Реальная SIM-карта оператора. Нужна для end-to-end проверки, когда сервис проверяет тип линии, HLR-запись, страну или маршрут доставки.
- Тестовый номер без маршрутизации. Используется для проверки формата E.164, заполнения базы и обработки ошибок валидации. Такой номер не должен случайно звонить настоящему абоненту.
Почему виртуальные номера не всегда проходят проверку
Сервис может определить, что номер относится к фиксированной линии или Non-Fixed VoIP, ещё до отправки OTP. Google Voice, TextNow, Skype и часть бесплатных SMS-сайтов часто попадают в эту категорию. Пользователь при этом видит расплывчатое сообщение вроде «проверка не выполнена» и повторяет запрос, хотя проблема связана не с кодом, а с классификацией номера.
Личная SIM-карта создаёт другую группу проблем. Номер быстро получает ограничения частоты, связывается с тестовой учётной записью и становится точкой конфликта для команды. Пять QA-инженеров не смогут надёжно использовать два телефона в параллельных сценариях, а CI не должен ждать, пока сотрудник вручную перепишет SMS.
Сравнивать нужно не только цену номера. Если дешёвый VoIP-номер часто отклоняется, несколько повторных попыток и часы отладки сводят экономию на нет. У реальной SIM-подписки есть собственная стоимость, зато она проверяет тот же класс маршрута, который видит живой пользователь.
Какие сценарии требуют реального номера
Регистрация и восстановление доступа
Для обычного signup-теста создайте аккаунт, запросите код, введите его и проверьте состояние после подтверждения. Отдельно проверьте повторную отправку, просроченный код, неверный код и повторное использование уже подтверждённого номера. Разовая активация подходит, если после первого сообщения номер больше не нужен.
Повторная 2FA-проверка
Новый браузер, смена пароля или необычный регион могут вызвать второй запрос. Здесь одна активация часто недостаточна: номер должен принять SMS в нескольких сессиях. Используйте выделенную аренду на срок теста или тестовый номер платформы, если внешний маршрут не входит в цель проверки.
Проверка разных стран
Формат телефона, шаблон сообщения, задержка оператора и правила платформы зависят от региона. Составьте матрицу «сервис + страна» и запускайте по одному номеру на комбинацию. Для приложений с аудиторией в Юго-Восточной Азии отдельно проверьте Индонезию, Филиппины и Малайзию; европейские сценарии нельзя считать заменой регионального теста.
Долгоживущая сессия
Бот Telegram, интеграция WhatsApp Business или тестовая учётная запись для поэтапного релиза могут жить днями. Разовый номер, который исчезает после первого кода, здесь создаёт ложный результат. Нужен закреплённый номер с закрытым входящим ящиком на весь срок сценария.
Smoke-тест после релиза
Минимальный production smoke-тест проверяет живую регистрацию, получение OTP и переход в подтверждённое состояние. Он должен быть коротким: один номер на сервис и один код после каждого релиза. Такой тест ловит проблемы маршрутизации и задержку доставки, которые staging с моками не покажет.
Как подключить получение OTP к CI
У провайдера с REST API базовая последовательность выглядит так:
- Создайте заказ, передав идентификатор сервиса и страны.
- Сохраните order ID и выданный номер в контексте теста.
- Запустите действие регистрации в приложении.
- Запрашивайте статус входящего SMS с интервалом около трёх секунд.
- После получения извлеките код регулярным выражением, например
\d{4,8}, и заполните поле OTP. - Проверьте состояние после входа, затем запишите order ID в лог сбоя.
POST /api/v1/orders
{
"service": 14,
"country": 22
}
GET /api/v1/orders/{orderId}/sms
В ответе должны быть как минимум идентификатор заказа и номер. Статус ожидания не является ошибкой. Настройте общий тайм-аут теста, а не бесконечный цикл. Если SMS не пришла за отведённое окно, заказ должен завершиться предсказуемо; у некоторых сервисов разовая активация автоматически возвращает кредит после 20 минут без доставки.
Для большого набора тестов webhook удобнее постоянного опроса: провайдер сам отправляет событие на ваш endpoint. Секрет API храните в CI secrets, не в репозитории, выводе тестов или скриншотах.
Dev, staging и production: разные правила
Development
В локальной разработке мокируйте отправку. Это ускоряет проверку формы, сообщения об ошибках и срока действия OTP. Реальный номер оставьте для нескольких сценариев, которые действительно проходят через внешний сервис.
Staging и QA
Здесь полезна карта сервисов и стран в конфигурации. Каждый запуск получает свежий заказ, передаёт номер в тестовый контекст и ждёт код. Для сценария «создание аккаунта → изменение настройки → повторная проверка» используйте аренду, которая сохраняет один номер между шагами. Не делите один номер между параллельными запусками.
Production
Smoke-тесты должны использовать минимальный набор данных и не создавать лишние аккаунты. Установите лимит частоты, храните только технический идентификатор заказа и удаляйте полученный код из логов. Реальный номер не делает тестовую учётную запись безопасной автоматически.
Практический выбор номера для QA
| Задача | Подход |
|---|---|
| Проверка формы и базы | Синтетические номера без маршрутизации |
| Unit-тесты OTP | Мок или stub SMS-провайдера |
| Ручная разовая регистрация | Временный номер, если код не секретный |
| CI с фиксированным ответом | Номер платформы Firebase или Twilio |
| Реальный WhatsApp, Telegram или Google flow | Номер с реальной SIM-картой оператора |
| Несколько сессий | Выделенная аренда на время теста |
BinOTP можно рассматривать как пример сервиса, где в контексте измерены 221 страна и 9.213 сервисов; показатель доставки менее чем за 60 секунд составил 79,4% в выборке из 2.000 кодов. Эти цифры относятся к измерению от 8 сентября 2026 года, а не являются гарантией для каждой страны или платформы.
💡 Рекомендуемое решение: BinOTP
- Поддержка 180+ стран и 400+ сервисов
- Код обычно приходит за 5 секунд
- Оплата только за полученный код — от $0.02
- API для разработчиков
Ошибки, которые часто портят тесты
- Не используйте личный номер в dev или staging: он попадёт в логи и аналитику.
- Не храните OTP и PII в отчётах CI. Временный номер не превращает персональные данные в безопасные.
- Не полагайтесь на один общий номер: его история, лимиты и состояние будут влиять на следующий запуск.
- Не называйте публичный inbox секретным каналом. Любой посетитель может увидеть сообщение.
- Не запускайте десятки заказов одной пары «страна + сервис» без проверки лимитов пула.
- Не заменяйте все реальные проверки моками. Перед релизом оставьте хотя бы один разрешённый end-to-end сценарий.
FAQ: тестирование SMS и 2FA
Можно ли тестировать OTP полностью без телефона?
Да, если проверяются только логика, форма, база и переходы состояний. Для доставки через реального оператора нужен маршрутизируемый номер.
Чем sandbox отличается от реального номера?
Sandbox возвращает заранее заданный ответ внутри тестовой инфраструктуры. Он не показывает, как внешний сервис классифицирует номер и доставляет SMS через оператора.
Какой срок ожидания поставить в CI?
Зависит от SLA и региона. Зафиксируйте конечный тайм-аут, записывайте время запроса и доставки, а после превышения лимита завершайте заказ и помечайте причину сбоя.
Дополнительный контекст есть в материалах о QA-чек-листе SMS и OTP и о построении поддержки интернет-магазина. BinOTP подходит для отдельных задач с реальными SMS, но тип номера, длительность аренды и правила хранения данных нужно выбирать по сценарию, а не по рекламному обещанию.