For the bulk of an E2E suite, catch SMS before it reaches a carrier and read the code over HTTP: either with a mock you host yourself or a hosted mock inbox. Keep real SMS for a small separate delivery check, and avoid hard-coded backdoor codes in application code.
At a glance
| Approach | Real SMS sent | Code readable by tests | App code changes | Main risk |
|---|---|---|---|---|
| Real SMS to a team phone | Yes | No (manual) | None | Slow, costly, cannot automate |
| Hard-coded test code (e.g. 000000) | No | Yes (fixed) | Backdoor in app | Backdoor reaching production |
| Provider test credentials | No | No | Credential swap | Message never reaches anything you can read |
| Real-number inbox service | Yes | Yes | None | Carrier latency, per-number cost, filtering |
| Self-hosted mock | No | Yes | Point SDK at mock | You build and maintain provider formats |
| Hosted mock inbox (otpmock) | No | Yes | Point SDK at mock | Does not test carrier delivery |
Real SMS
Sending real texts in tests is the most realistic option and the least automatable. Delivery time varies, every run costs money, and a human or a device farm has to read the code. It is worth keeping as a small smoke check that your production sender and templates work, not as the way your suite logs in.
Hard-coded backdoor codes
Accepting a fixed code for certain numbers is quick to add and fast in tests. The cost is that the backdoor lives in application code. One wrong environment flag and it works in production. It also skips the code path you are trying to test: generating, sending and checking a real code.
Provider test credentials
Some providers offer test credentials or magic numbers that return a canned success without sending. They are useful for unit-level checks of your request format, but the message goes nowhere you can read, and verification products are often not covered. See Twilio test credentials: limits and alternatives.
Real-number inbox services
Services such as Mailosaur and MailSlurp rent you real phone numbers and expose received texts through an API. They test the full carrier path, which is the right tool when that is what you want to verify. The trade-offs are carrier latency, a limited set of numbers that parallel tests have to share, and carrier filtering of verification traffic. See otpmock vs real-number SMS inboxes.
Self-hosted mocks
WireMock, LocalStack or a small custom server can stand in for your provider. They are free and run offline, but you write and maintain the response formats, Verify-style flows and a way to read codes back, and they need to be reachable from staging. See otpmock vs a self-hosted SMS mock.
Hosted mock inbox
A hosted mock speaks your provider's API, keeps messages in an inbox and lets tests read codes over HTTP. otpmock emulates fifteen providers including Twilio, Vonage, AWS SNS, Infobip and Sinch, with Verify APIs for eight of them, including Twilio, Vonage, Infobip, Sinch and Plivo. You change one SDK option in test environments and nothing reaches a carrier.
FAQ
Which approach should most teams use?
A mock (self-hosted or hosted) for the main E2E suite, plus a small real-SMS check if carrier delivery matters to you. Avoid backdoor codes in application code.
Does a mock inbox replace production monitoring?
No. It tests your application's behaviour. Monitor real delivery rates with your provider's own reporting.
Product names are trademarks of their owners; otpmock is not affiliated with them. Descriptions of other products reflect their public documentation as of October 2026. Check their sites for current features and pricing.
The free plan includes 100 messages a month. No card required.
Get a free API key