Testing a website end-to-end often requires checking email related functions such as welcome messages, reset password, and much more. Ensuring this connection to the user works is often very critical. However, even when we discount the time needed to interact with the system, manually verifying the reciept of an email is a tedious and time consuming process. To automate this, we have several options.
With the un-modified system, we can have the email sent to an email account that you control. The test progream will connect to the mail server and get a list of messages. Have it continuously poll the server for a specific duration while waiting for the expected message to appear.
In many cases, it is enough to test that attempt is made. Check for a function call in JS or api call of some sort. This is likely to require a modified system, but its possible to listen to an outbound api call and accept that as good enough.
With a modified system, the test can do something else instead of sending an email. For example, write a message to a file or call a different function. This relies on solid unit tests. You are trusing the code which sends the email, but you are testing everything else up until that point.
Another method, similar to the one from the un-modified system, is to send a modified email with a special identifing key, such as the Unix timestamp combined with test ID, so that you can query the mail server just once later on. This can be used when you have an upper bound on email delivery time.
Remember to sanity check yourself and look at how the emails look visually in common programs such as Gmail, Outlook, Yahoo Mail, etc.
As with all things in tech there may be a much more elegant solution for your specific use case.