How to Test Email Verification Flow

Email verification confirms the user owns the email they signed up with. Broken verification blocks account access. Too-easy verification invites abuse. This guide covers testing the flow end-to-end.

February 02, 2026 · 3 min read · How-To Guides

Email verification confirms the user owns the email they signed up with. Broken verification blocks account access. Too-easy verification invites abuse. This guide covers testing the flow end-to-end.

What to test

Triggering verification

  1. Signup sends verification email
  2. Resend option available (with rate limit)
  3. Can resend after 60 seconds / configurable
  4. Account creation succeeds even if email not yet verified (per design)
  5. Some features may be gated behind verification

Email

  1. Arrives within expected time (<5 min typically)
  2. From correct sender (verified: SPF, DKIM, DMARC)
  3. Subject line clear ("Verify your email for MyApp")
  4. Body identifies user
  5. Link prominent and clickable
  6. Link is unique per user
  7. Link has expiration (often 24-48 hours)

Link

  1. Tap / click opens verification
  2. Deep link opens app (mobile)
  3. URL also works in browser
  4. Single-use: second click expired
  5. Invalid / corrupted URL graceful error
  6. Expired URL offers resend

Post-verification

  1. Status updates: user.email_verified = true
  2. UI reflects verified state
  3. Welcome flow continues (or user redirected appropriately)
  4. Feature unlocks apply

Edge cases

  1. User clicks link while unauthenticated → login first, then verify
  2. User clicks link on different device — user associated correctly
  3. Multiple verification attempts — one succeeds, others expired
  4. User unsubscribes from verification emails — design decision (block or allow)
  5. Email typo at signup → user never receives → needs change-email flow
  6. Mailbox full → bounce → retry logic
  7. Spam filter → user cannot find → "check spam" messaging

Security

  1. Link cannot be guessed (cryptographically random)
  2. Link bound to specific user ID
  3. Rate limit on resend (prevent email bombing)
  4. No sensitive data in email link (signed token, not password)
  5. Verification action requires no login (link alone should suffice)
  6. Cross-account risk: user A's link works for user B? No.

Change email

  1. If user changes email, old email sent "Your email was changed" notification
  2. New email receives verification link
  3. Until verified, old email still the account email (or both temporarily)
  4. Abandoned change expires
  5. Re-change before verification overwrites

Accessibility

  1. Email subject / preview renders in screen-reader-friendly clients
  2. Verification page accessible
  3. Keyboard navigable

Multi-client

  1. Link works in Gmail mobile, Outlook, Apple Mail, web Gmail, etc.
  2. Link not clipped / truncated
  3. Link wrapped URL (some clients wrap) still functional

Localization

  1. Email in user's locale (if offered)
  2. Time zone respectful ("Link expires Feb 15")
  3. Currency / locale formatting if relevant

Testing approach

Manual

Automated

End-to-end


def test_verification(page, test_inbox):
    # signup
    page.goto("/signup")
    page.fill("#email", test_inbox.address)
    # ... fill rest
    page.click("text=Sign up")
    # fetch email
    email = test_inbox.wait_for_email(subject_contains="Verify")
    link = email.extract_link()
    page.goto(link)
    # verify success state
    expect(page.locator("text=Email verified")).to_be_visible()

Fix patterns

Idempotent verification

Verification endpoint can be called multiple times with same token without error (second is no-op).

Graceful expiry

Expired link → user lands on "Link expired. [Resend]" page with one-click resend.

Visible status

User's account dashboard shows "Email verified" or "Pending verification — resend" clearly.

Progressive disclosure

Non-verified users can use basic features; high-trust actions (withdraw, post publicly) require verification.

Common production bugs

  1. Link in email wraps across lines, breaks when pasted in browser
  2. Deep link works on iOS but not Android — intent filter missing
  3. Resend spams user without rate limit
  4. Link remains valid after verification — reuse could re-trigger actions
  5. Email change not propagated to all systems — verified in auth, old email in newsletter

How SUSA handles verification

SUSA drives the signup → wait for verification → deep link handling. For email capture, pair with test inbox. Findings include:


susatest-agent test myapp.apk --username test+{uuid}@testinbox.example --persona curious

Email verification is deceptively simple and has many failure modes. Test every client and every edge case.

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free