Verification testing

Verification emails require more than checking whether they arrived

Published August 2026. A complete test case should connect triggering, sending, delivery, verification, and expiry, while covering what happens to an old code after a resend.

Map the verification code lifecycle first

When a user clicks Send, the system creates a code, records its validity period, queues the message, and waits for verification. Seeing the email arrive proves only one part of the process; it does not prove that the code is correctly linked to the account, validity period, and one-time-use rules.

Test records should include at least the target email address, trigger time, task ID, delivery time, and verification result. Use an isolated test address rather than a personal long-term inbox.

Verify every detail on the success path

The six-digit code in the email must match the current session, and the validity-period message must match the server-side rule. After copy and paste, accept digits only and do not misinterpret spaces or interface formatting.

After successful verification, the flow should reach the correct page, and any persistent notice should no longer say “Verification code sent.” If the same code is used again, reject it or keep the completed state according to the product contract; do not create a second session.

Resending means more than sending another email

The Resend button should share the initial cooldown, remain disabled during the countdown, and show the seconds remaining. If the user returns to change the email address, codes for the old and new addresses must not work interchangeably.

Define whether the old code expires immediately when a new one is issued. During testing, record the delivery order and code value for both messages so network delays do not make a later email arrive first without context.

How to test expiry boundaries

Expiry checks should use server time, not a modified device clock. Submit during the middle of the validity period, near the boundary, and after the boundary, then check whether the feedback clearly distinguishes invalid codes, expired codes, and rate limits.

If the email arrives close to expiry, compare the trigger, queue, send, and receipt times. This helps determine whether the validity period is too short or the delivery queue experienced an abnormal delay.

Rate limits and empty addresses

An empty or incorrectly formatted email address must stop at the first step; no code should be sent to the backend. When repeated requests reach the limit, the interface should provide feedback in the user's language and explain the wait clearly.

After the rate limit is lifted, a new send must not carry an old login token, and leftover state from the previous logout must not jump directly to the code-entry step. The email address may be restored from the session, but the flow must restart from the public authentication entry point.

Keep the minimum test evidence

For defect reports, retain only the template version, task ID, time, masked address, and error feedback. Valid codes, complete login links, and real identity details should not remain in screenshots or shared documents.

After a fix, retest with a new address, identifier, and verification code to avoid opening an old message by mistake. Confirm the four result groups—success, old code, expiry, and rate limiting—before closing the test entry point.

Run a live test

Create an isolated address on the home page and put the unique case ID in the email subject.