7 September 2026
If your app verifies users by phone, the verification step is usually the one gap in your end-to-end tests. Everything up to "we sent you a code" is easy to automate; actually receiving that code is not, because a real SMS goes to a real phone, and your laptop isn't one. So teams skip it, mock it, or test it by hand once and hope it keeps working.
You can close that gap by renting a real number over an API, pointing your signup flow at it, and reading the inbound SMS back in the test. This post shows the shape of that, and where the tooling for it already exists.
Mocking the SMS step is fine for unit tests and fast CI runs — it checks your own code path. What it can't catch: a misconfigured sender ID, an SMS route that a carrier has started filtering, a template change that trips a spam rule, or an expired provider credential. Those only show up when a real message tries to reach a real handset.
The pragmatic split is: mock in unit tests, and keep one real end-to-end check that runs on a schedule (nightly or on release) rather than on every commit, so cost and rate limits stay low.
1. Rent a number over the API. Use an instant rental for a one-shot verification; the response includes the number and a rental ID you poll for messages.
2. Drive your signup or login flow with that number — in Playwright or Cypress, fill the phone field and submit, exactly as a user would.
3. Wait for the inbound SMS. Poll the rental (or receive it via webhook) with a timeout of 60–90 seconds, then pull the code out with a regex like /\b\d{6}\b/.
4. Enter the code in your app and assert verification succeeds. Then submit a deliberately wrong code and assert it is rejected — both directions matter.
5. Let the rental expire. Instant rentals close themselves after the window; no cleanup step needed.
sms-florin rents real UK numbers (EE and Three SIMs, not VoIP) and is built for this use case, not just manual rental. There's a REST API, an npm SDK with a waitForSms helper that does the polling and timeout for you, webhooks if you'd rather be pushed the message than poll, and a GitHub Action (sms-florin-otp-action) for wiring the whole rent-and-receive step into a workflow.
Failed instant rentals are refunded automatically, so a flaky run where the code never arrives doesn't cost you. Pricing is per rental and visible on the pricing page without an account.
Run the real end-to-end test on a schedule, not on every push — nightly against staging is usually enough to catch a broken send before users do.
Use a six-digit regex anchored on word boundaries rather than "first number in the message", so a code like 452301 isn't confused with a year or an order number in the same SMS.
If you also send email verification, the same pattern works with a disposable inbox instead of a number (receivemail.dev is the email-side equivalent).
If what you actually want is to know that production SMS delivery is working right now — not just at test time — that's continuous monitoring rather than a test, and otp-watch runs that same check on a schedule against your live flow.
Ready to try it? Browse services and prices — no signup required to see availability. Or rent directly from Telegram: @smsflorin_bot.