Tests that depend on a real inbox or phone number are slow, flaky and hard to scale. Teams sometimes create workarounds that fetch a code directly from logs or a database. Without tight boundaries, the workaround can weaken the control the test is supposed to validate.
Separate test verification from normal communication
A controlled test environment can provide an administrative method to retrieve an OTP for a test identity, avoiding real email or SMS delivery. WebFrolic documents this pattern for test users and test SMS numbers, while the test-user feature itself is disabled by default.
Make the boundary explicit: test identities are configured through lifecycle settings and the lookup method is authorised for the test context. Never accept a client-supplied email address alone as proof that a caller can read that identity’s OTP.
Preserve OTP security properties in tests
A code should be tied to the identity and transaction for which it was issued, expire according to policy and be invalidated after use. Tests should verify these properties rather than bypass them. A test API can return the code while still exercising the normal issuance and validation path.
Avoid writing OTP values to shared CI logs or long-lived artefacts. If the code must reach a test runner, minimise exposure and prevent unrelated jobs or users from reading the response. Keep admin credentials out of the repository.
Test the failure cases deliberately
Verify that a code for one account is rejected for another, a used code cannot be replayed and an expired code is denied. Test concurrent requests and repeated delivery attempts. These cases are not optional just because the happy-path suite is green.
Also test misconfigured test domains and disabled lifecycle settings. A clear failure is safer than silently routing test logic into real communication channels or normal-user paths.
Protect the administration surface
An API that retrieves test OTPs is more sensitive than an ordinary test helper. Restrict it to suitable administrative roles, dedicated environments or explicit test-user classifications. Log access to the helper without logging unrelated secrets.
Review the helper during release and environment changes. Ensure ordinary user roles cannot invoke it, and do not expose it to public networks unless there is a documented, approved need. Automation convenience should have a clear boundary and shutdown procedure.
The point
Use test-only identities and explicit lifecycle settings. Then: use test-only identities and explicit lifecycle settings; keep code expiry and one-time-use checks active; prevent OTPs and admin secrets leaking into CI logs.
