Application accepted the action
The signup or reset endpoint returns the expected state and identifies the mailbox that should receive the message.
Create an isolated address, trigger the product workflow, wait for delivery, inspect the message, and assert the state the user experiences.
QA teams can use mails0 to test end-to-end email workflows with real inboxes instead of mocking the application's send function. A robust test creates or assigns an isolated mailbox, triggers the user action, waits with a deadline, validates sender and content, follows the code or link, and cleans up its state.
Assert delivery and user-visible content as separate outcomes
The signup or reset endpoint returns the expected state and identifies the mailbox that should receive the message.
The test waits for an inbound email with an explicit timeout instead of assuming the provider accepted it.
The code or link works, and the browser or API reaches the verified state a user needs.
The signup or reset endpoint returns the expected state and identifies the mailbox that should receive the message.
The test waits for an inbound email with an explicit timeout instead of assuming the provider accepted it.
The code or link works, and the browser or API reaches the verified state a user needs.
Create a provisional inbox or reserve a unique address so previous messages cannot match.
Submit the form or API request and record the expected recipient and starting time.
Poll or subscribe with a deadline that is long enough for real delivery but short enough to keep CI actionable.
Check sender, recipient, subject, required copy, link host, and any code format.
Follow the link or enter the code and assert the final application state.
Delete disposable state while keeping message IDs, timings, and redacted test evidence for failures.
A shared inbox accumulates stale messages and forces tests to guess which result belongs to the current run. Fixed sleeps then hide delivery variance while making the suite unnecessarily slow.
Use unique recipients, record the trigger time, wait for a matching inbound message, and fail with clear diagnostics. If parallel tests share a domain, bind assertions to mailbox identity rather than subject text alone.
| Flow | Minimum assertion | Higher-confidence assertion |
|---|---|---|
| Signup verification | Code or link arrives. | Link verifies only the intended pending account and cannot be reused. |
| Password reset | Reset message arrives. | Token expires, is single-use, and does not disclose account existence. |
| Invitation | Invite identifies organization and inviter. | Wrong recipient cannot accept; revoked invite fails. |
| Receipt or confirmation | Expected transaction data appears. | Amounts, currency, identifiers, and attachments match source records. |
| Delivery failure | Application records a failure state. | Retry, suppression, and user-visible recovery paths are exercised. |
Product behavior is verified against the mails0 source and documentation. External comparisons link to official vendor documentation checked on 2026-08-15.
Mocks are useful for unit tests, but they cannot prove DNS, provider, routing, parsing, template, link, or inbox behavior. Keep unit mocks and add a smaller end-to-end email suite.
Use an explicit timeout based on the environment and expected provider latency. Record arrival time and fail clearly instead of using an unbounded poll or a fixed sleep.
Yes, when each test has an isolated mailbox or uniquely addressable recipient and the assertions bind to that identity.
Use provisional mailboxes for isolated receive-only tests when limits fit. Use a controlled self-hosted or persistent test environment when suites require stable domains, sending, or higher volume.
Start with a receive-only temporary mailbox. Move to a permanent identity or self-hosted deployment only after the workflow reaches a real email value event.