checklistemaildeliverabilityqaweb

Transactional Email Testing Checklist: 40 Things People Forget

A classic I’ve caught more than once: registration works, but the password-reset email lands in spam. Or it arrives with “Hello, {{first_name}}” instead of a name. Or the “confirm your email” link expires in 15 minutes while the email takes 20 to arrive. Nobody tested it, because “it’s just an email, what could break.”

Plenty breaks — and the cost is high: an undelivered password-reset email = a locked-out account and a support ticket; an email in spam = a lost signup. Transactional emails (welcome, password reset, receipts, alerts) are part of the product, and you test them like the product.

Why email is QA’s blind spot

An email travels a long path: an event in the app → a template → rendering with variable substitution → sending via a provider (SES/SendGrid/Postmark) → the recipient’s filters → rendering in a specific client. A bug can live at any seam, and only whoever actually opens the email in a real inbox sees it — not “the send returned 200.”

Trigger and content

  • The email arrives on the right event and exactly once (not on every request retry).
  • The right template was used (not welcome instead of a receipt).
  • Variables are filled: name, amount, date, link. Test empty/missing fields — there must be no “{{name}}”, “undefined”, “null”, or blank strings.
  • Plurals and formats: “1 item / 2 items / 5 items,” amounts and dates by locale.
  • Special characters and Unicode in the name/data don’t break the layout or inject HTML (escaping — otherwise XSS via email).

Deliverability (does it even arrive)

  • SPF, DKIM, DMARC are set up and pass — otherwise mail goes to spam or bounces.
  • Run it through spam scoring (mail-tester and the like): attachments, “spam words,” broken HTML, a missing plain-text part all hurt reputation.
  • Correct From / Reply-To / Return-Path, a recognizable sender name.
  • Check delivery in Gmail, Outlook/Office365, Apple Mail, and regional providers — everyone’s filters differ.
  • Bounces and complaints are handled (hard bounce → don’t send again).
  • Links point to the right environment (not staging from a prod email — a frequent, embarrassing bug).
  • The token lifetime is reasonable and aligned with delivery latency (the link mustn’t expire before the email arrives).
  • One-time links (password reset, confirmation) work exactly once.
  • Links don’t break on line wrapping in the client; tracking redirects don’t fall apart.
  • Unsubscribe works and is mandatory for bulk mail (List-Unsubscribe header + link).

Rendering in email clients

  • Subject and preheader are meaningful, not truncated, no “(no subject)”.
  • There’s a plain-text version (multipart) — not only HTML.
  • Dark mode: the email is legible (dark text on a dark background is the classic fail).
  • Images off (the default in many clients): alt present, the email makes sense without images, key info isn’t inside an image.
  • Gmail clipping: an email heavier than ~102 KB gets clipped — keep it compact.
  • Outlook (the Word engine) breaks modern CSS — test it separately; the mobile layout is responsive.
  • Check rendering via caniemail/preview services, not “it opened fine in my Gmail.”

Timing, duplicates, retries

  • No duplication: a send retry or a double click doesn’t send two emails (idempotency by event key).
  • Latency is acceptable; critical ones (password reset, OTP) are fast.
  • The queue survives a provider outage: the email isn’t lost and isn’t sent 5 times after recovery.
  • The email language = the user’s language/locale; RTL doesn’t break.
  • For marketing — a physical sender address and unsubscribe (CAN-SPAM/GDPR).
  • Personal data in the email is minimal (emails get forwarded and logged).

Checklist (quick pass)

  • Arrives on the right event, exactly once, the right template.
  • All variables filled; empty fields don’t produce ”{{…}}”/undefined; escaping in place.
  • Plurals, amount/date formats by locale.
  • SPF/DKIM/DMARC pass; spam score green.
  • Delivery verified in Gmail / Outlook / Apple Mail / regional providers.
  • From/Reply-To correct; bounces handled.
  • Links point to the prod environment; tokens one-time and don’t expire before delivery.
  • Unsubscribe works (link + List-Unsubscribe).
  • Subject/preheader not truncated; a plain-text version exists.
  • Legible in dark mode and with images off (alt in place).
  • Not clipped in Gmail (<~102 KB); Outlook and mobile checked.
  • No duplication on retries/double click; critical emails are fast.
  • Correct locale; for bulk mail — sender address and consent.

In short — what to take with you

  • A transactional email is part of the product, not “just an email.” Open it in a real inbox.
  • Deliverability (SPF/DKIM/DMARC + spam scoring) matters more than the layout: an undelivered email = 0.
  • The three most common bugs: an empty variable (“{{name}}”), a staging link from prod, an expired token.
  • Test rendering in dark mode, with images off, and in Outlook — that’s where it breaks.
  • Send idempotency — so a retry doesn’t turn into 5 emails.

Further reading: Can I email — support across email clients · Mail-Tester — spam-score and SPF/DKIM check · DMARC.org — on email authentication