A Test Mail Sink for a Website Staging Environment
A staging copy of a website often holds copies of real customer records. If the staging site can send email, a routine test of an order confirmation could reach a real person. This article proposes, conditionally, a mail sink: a boundary that would catch every outgoing message in staging and deliver it only to a controlled inbox.
The idea
The staging site would never talk to the real mail route. Its outgoing mail setting would point to a sink that accepts everything and forwards nothing to the original recipient. The important design choice is that substitution happens at the boundary, not in each template. Templates change often, and one forgotten template would be enough to leak.
Primary artifact: recipient substitution matrix
If commissioned, the sink should apply a rule to every address field in every message.
| Address situation | Proposed action |
|---|---|
| To is a synthetic test address on an agreed test domain | Deliver to the test inbox |
| To is a staff address on an explicit allowlist | Deliver to that staff member, if the team accepts this |
| To looks like a real customer address | Replace with the sink inbox, keep original in a header or log note |
| CC or BCC present | Remove all, then apply the same rules to each |
| Reply-To present | Replace with a harmless test address |
| Recipient empty or malformed | Do not send; record as rejected |
| Many recipients in one message | Reject, because a test rarely needs a bulk send |
The subject could also be prefixed with "[STAGING]" and the original intended recipient shown in the body, so testers can see what would have happened.
Branching choices
If the team wants staff to receive real-looking messages, use the allowlist but keep it short and reviewed. If not, send everything to one shared inbox. If other systems, such as a newsletter tool or a notification service, send mail independently of the website, they sit outside the sink and need their own checks. List them before commissioning, because the sink only covers what passes through it.
Safe synthetic test procedure
- Create test customers whose addresses use only a domain the team controls or one reserved for testing, never a real person's address.
- Confirm the staging data contains no real customer addresses, or that the sink rules cover them.
- Trigger one message of each type: order confirmation, password reset, contact form acknowledgement, internal notification.
- Check each arrives only in the sink inbox, with the staging prefix.
- Repeat once with a real-looking but fictional address on a test domain, and confirm substitution occurred.
- Repeat with CC and BCC set, and confirm they were stripped.
Hypothetical worked example
Suppose a tester places a staging order as test-buyer@example-test.invalid and, by mistake, a copied record belongs to a person with a real-looking address. Both orders trigger confirmations. The expected result is two messages in the sink inbox, the second labelled as originally intended for the real-looking address, and zero messages elsewhere.
Stop conditions
Stop all testing if any message appears outside the sink inbox, if the sink is unreachable and the site falls back to normal sending, or if a message type cannot be triggered through the sink. The failure mode matters most: when the sink is down, the staging site should fail to send rather than send directly.
Acceptance checks
- Every row of the matrix has been exercised at least once.
- Switching the sink off results in no outgoing mail, not direct delivery.
- A written list shows which mail sources are covered and which are not.
- The staging prefix appears on every captured message.
- A person who did not build the setup can repeat the procedure and get the same result.