An international signup form can look healthy on every dashboard while one country quietly converts at zero. The cause is often small: a trunk zero that was not stripped, a country code entered twice, or a validator that rejects a perfectly real number. Users see no error message; the code simply never comes.

This playbook explains how to group countries by numbering plan, which input habits to simulate, why end-to-end tests on real numbers catch what mocks miss, and how to run the checks automatically so formatting regressions surface before your conversion figures do.

Phone input is where international signups quietly die

Every product team eventually discovers that phone-number handling is a minefield: users type numbers with leading zeros, national prefixes, spaces, dashes, or their country code twice; validation libraries disagree with carriers; and an E.164 formatting bug in one country silently zeroes conversions there while every dashboard stays green. Because the failure is user-invisible — the SMS just never arrives — formatting bugs routinely survive for months. Testing them requires actually receiving messages in each format regime, not just unit-testing a regex.

A test matrix that reflects reality

Automating it into CI

The sustainable setup is a small suite that runs weekly and before releases: programmatically rent numbers in your top signup countries, drive the registration flow with each format variant, assert code arrival within an SLA, and alert on per-country regression. Keep libphonenumber (or equivalent) as the normalization source of truth, log the normalized output next to the raw input for every real signup, and formatting bugs become a dashboard line instead of a quarter-long conversion mystery in a market you can't see.

Which input variants belong in every country's test cases?

Once you have chosen representative countries, the next question is what to type into the field. Give every country the same set of variants, so results are comparable across markets and a regression stands out immediately.

For each variant, record three results: what the client sent, what the server stored after normalisation, and whether the SMS arrived. Every valid variant should produce identical E.164 storage and a delivered code. The invalid case should be rejected before any SMS is requested, so you are not paying for messages to impossible numbers.

Keep the matrix in version control next to the tests, and add a row whenever support reports a formatting complaint. Over time it becomes a record of how your users really type, which is more valuable than any specification.

  • National format with trunk prefix, as a local would write it on a business card.
  • International format with a plus sign and country code.
  • International format using 00 instead of the plus sign.
  • Country selected in a dropdown and the full national number, trunk 0 included, typed in the field.
  • Country code entered twice, once in the selector and once in the field.
  • Spaces, dashes, dots and brackets pasted from a contact card or email signature.
  • Leading or trailing whitespace and invisible characters from copy and paste.
  • A number with the wrong length for that country, which should fail with a clear message.

Lawful SMS verification only. Follow each platform’s terms. Ucode is not for bulk account farming or ban evasion.

Key takeaways

  • Test families, not flags: trunk-prefix, variable-length and fixed-length plans cover most bugs.
  • Type like a local: feed in the formats real users enter, not the tidy international version.
  • Prove delivery: a passing validator means little unless a real SMS arrives.

In short

Phone formatting bugs hide because failed SMS delivery rarely shows up on dashboards. Test by numbering-plan family, submit numbers as locals type them, normalise with a maintained library, confirm real delivery on numbers in each target country, and alert on per-country regressions.