Skip to main content

Integration testing guide

MailSlurp gives QA and release teams real inboxes, real phone numbers, deterministic wait methods, and message quality tooling. The goal is not just "can I receive one email" but "can I prove the whole workflow behaved correctly before we ship."

email testing

What teams use MailSlurp for

  • Signup and verification flows that send email or SMS
  • Password reset and magic-link journeys
  • OTP and MFA checks
  • Notification and transactional email assertions
  • Release gates for delivery, rendering, and message quality

Core release workflow

1. Create isolated inboxes or phone numbers per run

Fresh resources keep tests deterministic and make it easy to trace failures back to one build, one suite, or one campaign.

const inbox = await mailslurp.createInbox();
// { id: '123', emailAddress: '123@mailslurp.com' }

Best practice:

  • Use one inbox per test run or scenario when you can.
  • Use expiring inboxes for short-lived suites.
  • Keep naming and tags aligned with your CI pipeline or release identifier.

2. Wait for real messages instead of sleeping

MailSlurp wait methods let you block until a matching message arrives. This is what removes brittle sleep() calls from browser or API tests.

// wait for the latest unread sms
const [sms] = await mailslurp.waitController.waitForSms({
waitForSmsConditions: {
count: 1,
unreadOnly: true,
phoneNumberId: phoneNumber.id,
timeout: 30_000
}
});
// extract a code from body with regex
expect(sms.body).toContain('Your code: 123');
const [, code] = /.+:\s([0-9]{3})/.exec(sms.body);
expect(code).toEqual('123');

Use wait methods when you need to assert:

  • a message arrived
  • the recipient was correct
  • the subject or sender matched expectations
  • a code or link can be extracted and used in the next test step

3. Open, inspect, and validate message content

After a message lands, teams usually do one of three things:

  • extract links or OTP codes
  • open preview URLs for visual checks
  • validate content quality such as links, images, and supported email features
const {
// load this in a browser to view teh rendered HTML and interact with it
plainHtmlBodyUrl,
// or view full SMTP message
rawSmtpMessageUrl
} = await mailslurp.emailController.getEmailPreviewURLs({
emailId: email.id!
});
const { result } =
await mailslurp.emailController.checkEmailBodyFeatureSupport({
emailId: email.id,
});
expect(result.detectedFeatures).toContain(
EmailFeatureSupportResultDetectedFeaturesEnum.html_doctype
);
expect(
result.featurePercentages.find(
(it) =>
it.status === EmailFeatureSupportStatusPercentageStatusEnum.SUPPORTED
)?.percentage
).toBeGreaterThan(50);

Then deepen the check with:

4. Add release and post-send confidence checks

Single-message waits are useful in tests. Release teams usually add broader controls before launch:

Example projects

Loading examples...

Framework starting points

Practical patterns that reduce flakiness

  • Set explicit wait timeouts that reflect real delivery behavior in your environment.
  • Isolate inboxes or phone numbers so tests do not compete for the same messages.
  • Match on concrete fields such as recipient, subject, or unread status.
  • Keep message extraction helpers in shared test utilities instead of duplicating regex and parsing logic.
  • Use broader delivery checks before major releases instead of relying only on one test inbox.