Your staging environment uses 123456 as the OTP. Tests pass. CI is green.

Then production users complain: “I never received the code.”

Mock OTPs don’t test the thing that actually breaks—SMS delivery. And when you try to automate real OTP testing, you hit a wall: cloud devices don’t have SIMs you control, virtual numbers get blocked, and the workarounds cost more than they’re worth.

Here’s what actually works.

The Real Problem with OTP Testing

Most teams test 2FA one of three ways:

1. Mock/Static OTPs in staging

The developer sets the OTP to 123456 for test accounts. Fast, easy, completely useless for catching real issues.

What you miss:

  • Carrier delays (especially international)
  • SMS filtering and blocking
  • Rate limiting by telecom providers
  • Delivery failures on specific networks

2. Virtual phone numbers (Twilio, Mailosaur)

You get a programmable phone number and read incoming SMS via API. Sounds perfect until fintech apps block you.

Banks and payment apps maintain blocklists of VoIP/virtual number ranges. The same Twilio number that works in your staging environment will fail silently when production fraud detection kicks in.

From a real testing scenario:

“We automated our entire 2FA flow with Twilio numbers. Worked great for months. Then the bank’s fraud team updated their blocklist and every test started failing. We didn’t find out until a production user reported login issues.”

3. Cloud device platforms with shared SIMs

BrowserStack and similar platforms offer “SIM-enabled devices.” But these are shared phone numbers—you’re not the only one receiving SMS to that number during your test window.

BrowserStack’s SIM testing requires the “Desktop & Mobile Pro” plan at $249/month per parallel test. And you still don’t control the phone number.

Why Fintech Apps Need Real SIMs

Banking, payments, and fintech apps have stricter requirements:

Fraud prevention blocks virtual numbers. VoIP ranges are the first thing fraud detection systems block. Your test infrastructure becomes useless against production security.

Compliance auditors want real-device evidence. PCI-DSS and SOC2 auditors ask how you tested authentication flows. “We used mock OTPs” isn’t a satisfying answer.

Carrier-specific issues are invisible until production. SMS routing varies by carrier, country, and network conditions. A message that arrives instantly on Verizon might take 30 seconds on a regional carrier—or never arrive at all.

International OTP delivery is unreliable. If your users are global, you need to test SMS delivery to actual phones in those regions. Virtual numbers don’t expose these issues.

The Math: What OTP Testing Actually Costs

Virtual Numbers (Twilio)

Item Cost
Phone number $1-2/month each
Inbound SMS $0.0075/message
1000 tests/month ~$10/month

Sounds cheap until the fintech fraud team blocks your number range. Then you’re rebuilding your entire test infrastructure.

Cloud Platform SIM Testing

Platform Tier Required Cost
BrowserStack Desktop & Mobile Pro $249/month per parallel
HeadSpin Enterprise Contact sales
Perfecto Premium Contact sales

You’re paying premium pricing for shared phone numbers you don’t control.

Your Own Devices

Item Cost
Test phone $200-400 one-time
SIM card $10-20/month
DeviceLab license $99/device/month

Your phone. Your SIM. Your number. No one else receives your test OTPs. See our device cloud cost calculator for the full comparison.

How to Actually Test OTP with Appium

On a device you control, reading OTP from the notification bar is straightforward. Here’s the Appium approach:

java
// Step 1: Clear previous notifications
driver.openNotifications();
List<MobileElement> clearButtons = driver.findElements(
    By.id("com.android.systemui:id/dismiss_view")
);
if (!clearButtons.isEmpty()) {
    clearButtons.get(0).click();
}
driver.pressKey(new KeyEvent(AndroidKey.BACK));

// Step 2: Trigger the OTP (your app sends SMS)
loginPage.enterPhoneNumber("+1234567890");
loginPage.clickSendOTP();

// Step 3: Wait for notification and extract OTP
Thread.sleep(5000); // Wait for SMS delivery
driver.openNotifications();

MobileElement notification = driver.findElement(
    By.xpath("//android.widget.TextView[contains(@text, 'OTP')]")
);
String notificationText = notification.getText();
String otp = notificationText.replaceAll("[^0-9]", "");

// Step 4: Enter OTP
driver.pressKey(new KeyEvent(AndroidKey.BACK));
otpPage.enterOTP(otp);

This only works when:

  • You have physical access to the device (or remote access via DeviceLab)
  • The device has a real SIM receiving actual SMS
  • Notifications are enabled for the SMS app

On shared cloud devices, you’re fighting for notification access with other tests running on the same device.

Using Appium Settings for SMS Reading

For Android, the Appium Settings helper provides direct SMS access without opening notifications:

java
// Read SMS list directly
String smsResponse = driver.executeScript(
    "mobile: shell",
    ImmutableMap.of("command", "content query --uri content://sms/inbox --projection body")
).toString();

// Parse the latest message
Pattern pattern = Pattern.compile("\\b\\d{6}\\b");
Matcher matcher = pattern.matcher(smsResponse);
if (matcher.find()) {
    String otp = matcher.group();
    otpField.sendKeys(otp);
}

This requires SMS permissions and only works on devices where you control the Android shell. Cloud platforms typically don’t expose this.

The DeviceLab Approach

With DeviceLab, you connect your own devices—phones sitting in your office, with SIM cards you purchased, receiving SMS to numbers you control. No tunnels, no shared infrastructure—just direct P2P connections to your devices.

Your device, your SIM:

Your Office                    Your CI Runner
┌─────────────┐               ┌─────────────┐
│ Pixel 7     │◄── WebRTC ───►│ GitHub      │
│ +1-555-0123 │    P2P        │ Actions     │
│ Your SIM    │               │             │
└─────────────┘               └─────────────┘

When your test triggers an OTP:

  1. Your backend sends SMS to +1-555-0123
  2. Your Pixel 7 receives it (real carrier, real delivery)
  3. Your Appium test reads the notification
  4. Test continues with real OTP

No shared numbers. No virtual number blocklists. No premium cloud tiers.

What About iOS?

iOS OTP testing is harder because:

  • No direct SMS content access via automation
  • Notification reading requires specific capabilities
  • iMessage complicates SMS testing

Workarounds:

  1. Use the SMS autofill feature (iOS 12+) which automatically suggests OTP from messages
  2. Test on Android for SMS flow, iOS for UI validation
  3. Use email OTP as fallback for iOS automation

Testing Checklist for OTP Flows

Before you ship:

Test Case Mock OTP Virtual Number Real SIM
OTP arrives within 30 seconds No Maybe Yes
Retry after OTP expires Yes Yes Yes
Wrong OTP rejection Yes Yes Yes
Rate limiting (5 attempts) Yes Yes Yes
Carrier-specific delays No No Yes
International delivery No Maybe Yes
Fraud detection bypass No No Yes
Production-identical flow No No Yes

When Mock OTPs Are Fine

Not every app needs real SIM testing. Use mocks when:

  • Your app doesn’t handle payments or sensitive data
  • You’re testing UI flows, not delivery reliability
  • Development environment only (not pre-production)
  • OTP is email-based (easier to automate with Mailosaur)

But if you’re building fintech, healthcare, or anything with real security requirements—mocks aren’t enough.

Getting Started

If you already have test devices:

  1. Insert a SIM card you control (prepaid works fine)
  2. Connect to DeviceLab (curl -fsSL https://app.devicelab.dev/device-node/KEY | sh)
  3. Update your Appium tests to read from notifications
  4. Run from CI with real OTP delivery

If you’re evaluating options:

Need Solution
Quick prototype Mock OTPs, refactor later
Non-fintech production Virtual numbers + monitoring
Fintech/banking Real devices with real SIMs
Global user base Devices in each target region

The Bottom Line

Mock OTPs test your UI. Virtual numbers test your API. Real SIMs test what your users actually experience.

For fintech apps where OTP delivery is critical, there’s no substitute for testing on real devices with real carrier delivery. The cost of one missed OTP failure in production—support tickets, user churn, security concerns—exceeds a year of proper test infrastructure.

Your devices. Your SIMs. Real OTPs.


DeviceLab connects your physical devices to your CI pipeline. Test OTP flows, biometric auth, and carrier-specific behavior on phones you control. Get started free.

Last verified: December 2025