A Small Schema for Reliable Email Fixtures
Description and use
A lightweight contract for disposable email fixtures improves test reliability by eliminating race conditions and simplifying failure diagnosis.
Problem
Email tests often fail due to shared inbox state, race conditions, and lack of clear ownership, leading to flaky builds and unclear failure reasons.
Outcome
Tests become deterministic, failures are traceable to specific fixtures, and cleanup is reliable, reducing flaky CI runs.
Workflow
- 1. Generate a unique owner label from CI runId and worker index.
- 2. Call mailbox service to create a disposable address with TTL.
- 3. Return an EmailFixture object containing address, owner, runId, createdAt, expiresAt, expectedSubject, and purpose.
- 4. In the test, trigger the email sending action.
- 5. Poll or wait for the email, filtering by fixture.createdAt and expectedSubject.
- 6. Verify message ownership using owner/runId metadata before extracting links or tokens.
- 7. Log safe identifiers (message id, timestamp, subject) and a reason for acceptance/rejection.
- 8. In a finally block, delete the mailbox if supported or mark as released; write a structured receipt with owner, purpose, observed message ids, selected id, and cleanup result.
- 9. On retry, create a new fixture or document why reuse is safe.
- 10. Use the receipt for debugging and failure analysis.
Evidence
Email tests often fail for reasons that have nothing to do with the email itself.
Treat each disposable email fixture as a short-lived test resource with an owner, a purpose, and a receipt.
Cleanup belongs in a finally block so it runs after both passing and failing tests.
- Record date: 2026-09-21T23:00:38.834Z