Order success emails, Passwordless logins, testing rendering logic, how on earth can I test this?
Emails are not side effects!
Emails are crucial to your application’s functionality. Without a confirmation email or an “Order Success” you can be sure your company’s support team is going to know about it. And many an app’s USP is up-to-date notifications of actions in a system, emails, push notifications etc, so we sure better test them!
Of course, normally checking emails comes at the end of a testing process, and is done manually. In the old days, it would be done at the end of a “Regression Cycle” which has fallen out of favour, and for good reason! But how can a modern developer, pushing directly to main, be sure that all email functionality is acting as expected? Furthermore, with authentication mechanisms using OTP codes or Passwordless logins, how can we be sure that these processes haven’t broken?
Well, enter email integration testing. And at San Digital we have created a small, lightweight product to help you get started.
Mail Integrate
Mail Integrate is an easy-to-use queryable inbox that can receive messages on a custom domain created by you, for example, myapp.mailintegrate.com
.
Getting started is as easy as
- Creating a Mail Integrate account at app.mailintegrate.com
- Create a domain and API Token
- Start sending emails to any number of email addresses
@yourapp.mailintegrate.com
- Query the Messages API to receive a list of emails sent to that address.
Any email sent to your custom domain is accessible only by you and stored for up to 1 day.
Implementing automated testing
When using MailIntegrate in automated testing, the messages API provides a simple way of obtaining all messages associated with a user in an automated test.
Using a tool such as Cypress, a simple command can be created to query emails.
Cypress.Commands.add("queryEmails", (email: string) => {
return cy.request({
qs: {
email,
},
headers: {
Authorization: "Token " + Cypress.env("MAILINTEGRATE_API_KEY"),
},
method: "GET",
url: `${Cypress.env("MAILINTEGRATE_API_URL")}/messages`,
}).then(response => {
if (response.status !== 200) {
throw new Error("Error getting messages " + response.body);
}
return response.body.data
});
});
This can then be used in a test as simply as.
it("should send an email to the user", () => {
//call your app functionality
...
//test expected email was sent
cy.queryEmails(email).then(emails => {
expect(emails.length).eq(1);
expect(emails[0].subject).eq("Hey there! Something happened on our app.")
})
})
A fully working example can be found here mailintegrate-example
Open Api
Full details of the API Specification can be found here, OpenAPI Spec
Use Case - Passwordless Login
Passwordless Login is the hot new thing for all product managers, no need for users to remember a password, easy signup, but it causes problems when testing login.
If it’s the only way into the app, then you need email integration testing to test anything! Below we can see a useful example of how to
- Request a code
- Query your inbox
- Extract the OTP code
- Use the code to log in
const prefix = Math.random().toString(36).substring(7);
//new email address per test
const email = `${prefix}@${Cypress.env("MAILINTEGRATE_DOMAIN")}`;
cy.get("input[name='email']").type(email);
cy.contains("button", "Login").click();
cy.queryEmails(email).then(emails => {
const welcomeEmail = emails[0];
const accessCodeRegex = /( [\d]{6})/
const code = welcomeEmail.html.match(accessCodeRegex)[0].trim();
cy.get("input[name='code']").type(code);
cy.contains("button", "Submit Code").click();
})
Summary
Email Integration Testing is vital to any software project’s success and using MailIntegrate you can get reliable, cost-effective results set up quickly.
For more information please go to mailintegrate.com
Let’s do something great