# 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](/assets/email-testing.jpeg)

## 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.

```typescript
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.

```javascript
// 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

```typescript
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!
});
```

```typescript
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:

- [Email audit](/docs/email-audit/) for broken links, images, and quality review
- [Device previews](/docs/device-renders/) for client and viewport differences
- [Email compatibility](/docs/email-feature-check/) for feature support checks

### 4. Add release and post-send confidence checks

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

- [Deliverability tests](/docs/deliverability-test/) for expectation-based pass/fail checks across inbox or phone cohorts
- [Campaign Probe](/docs/campaign-probe/) for live campaign capture and review
- [Domain Monitor](/docs/domain-monitor/) and [Reputation](/docs/reputation/) for sender-health monitoring

## Example projects

<div data-component="DocsExamplesList" class="docs-card-grid docs-examples-list" data-example-terms="playwright, cypress, selenium, testcafe, webdriver, chromedriver, pytest, phpunit, junit, testng, robot, cucumber" data-example-count="27">
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/csharp-dotnet-core2-selenium" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Csharp Dotnet Core2 Selenium</span><span class="docs-card-description">csharp example repository: <code>csharp-dotnet-core2-selenium</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/csharp-playwright-nunit-sms-otp" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Csharp Playwright Nunit Sms Otp</span><span class="docs-card-description">csharp example repository: <code>csharp-playwright-nunit-sms-otp</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/csharp-specflow-mstest-selenium" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Csharp Specflow Mstest Selenium</span><span class="docs-card-description">csharp example repository: <code>csharp-specflow-mstest-selenium</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/java-gradle-junit5" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Java Gradle Junit5</span><span class="docs-card-description">java example repository: <code>java-gradle-junit5</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/java-maven-junit4" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Java Maven Junit4</span><span class="docs-card-description">java example repository: <code>java-maven-junit4</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/java-maven-selenium" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Java Maven Selenium</span><span class="docs-card-description">java example repository: <code>java-maven-selenium</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/java-testng-selenium" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Java Testng Selenium</span><span class="docs-card-description">java example repository: <code>java-testng-selenium</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/javascript-cypress-js" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Javascript Cypress Js</span><span class="docs-card-description">javascript example repository: <code>javascript-cypress-js</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/javascript-cypress-js-open-email" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Javascript Cypress Js Open Email</span><span class="docs-card-description">javascript example repository: <code>javascript-cypress-js-open-email</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/javascript-cypress-mailslurp-plugin" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Javascript Cypress Mailslurp Plugin</span><span class="docs-card-description">javascript example repository: <code>javascript-cypress-mailslurp-plugin</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/javascript-cypress-newsletter-signup" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Javascript Cypress Newsletter Signup</span><span class="docs-card-description">javascript example repository: <code>javascript-cypress-newsletter-signup</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/javascript-cypress-sms-testing" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Javascript Cypress Sms Testing</span><span class="docs-card-description">javascript example repository: <code>javascript-cypress-sms-testing</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/javascript-testcafe" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Javascript Testcafe</span><span class="docs-card-description">javascript example repository: <code>javascript-testcafe</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/javascript-webdriver-io" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Javascript Webdriver Io</span><span class="docs-card-description">javascript example repository: <code>javascript-webdriver-io</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/php-composer-phpunit" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Php Composer Phpunit</span><span class="docs-card-description">php example repository: <code>php-composer-phpunit</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/php-laravel-phpunit" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Php Laravel Phpunit</span><span class="docs-card-description">php example repository: <code>php-laravel-phpunit</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/playwright-codegen-recorder-nocode" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Playwright Codegen Recorder Nocode</span><span class="docs-card-description">playwright example repository: <code>playwright-codegen-recorder-nocode</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/playwright-email-testing" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Playwright Email Testing</span><span class="docs-card-description">playwright example repository: <code>playwright-email-testing</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/playwright-lowcode-testing" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Playwright Lowcode Testing</span><span class="docs-card-description">playwright example repository: <code>playwright-lowcode-testing</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/playwright-sms-testing" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Playwright Sms Testing</span><span class="docs-card-description">playwright example repository: <code>playwright-sms-testing</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/python2-pytest" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Python2 Pytest</span><span class="docs-card-description">python2 example repository: <code>python2-pytest</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/python3-django-playwright" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Python3 Django Playwright</span><span class="docs-card-description">python3 example repository: <code>python3-django-playwright</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/python3-robotframework" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Python3 Robotframework</span><span class="docs-card-description">python3 example repository: <code>python3-robotframework</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/ruby-capybara-cucumber-selenium" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Ruby Capybara Cucumber Selenium</span><span class="docs-card-description">ruby example repository: <code>ruby-capybara-cucumber-selenium</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/ruby-cucumber-test" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Ruby Cucumber Test</span><span class="docs-card-description">ruby example repository: <code>ruby-cucumber-test</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/rust-selenium-email-testing" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Rust Selenium Email Testing</span><span class="docs-card-description">rust example repository: <code>rust-selenium-email-testing</code></span></a>
<a class="docs-card docs-example-card" href="https://www.github.com/mailslurp/examples/tree/master/totp-mfa-auth0-selenium" target="_blank" rel="noopener noreferrer"><span class="docs-card-title">Totp Mfa Auth0 Selenium</span><span class="docs-card-description">totp example repository: <code>totp-mfa-auth0-selenium</code></span></a>
</div>

## Test framework guides

- [Cypress](/docs/cypress-mailslurp/)
- [Playwright](/docs/playwright/)
- [Selenium](/docs/selenium/)
- [WebdriverIO](/docs/webdriverio/)
- [TestCafe](/docs/testcafe/)
- [Pytest](/docs/pytest/)
- [PHPUnit](/docs/phpunit/)
- [JUnit](/docs/junit/)
- [TestNG](/docs/testng/)

## Platform and runner guides

- [CodeceptJS](/docs/codeceptjs/)
- [Robot Framework](/docs/robot-framework/)
- [Browserstack](/docs/browserstack/)
- [Tricentis Testim](/docs/testim/)
- [ACCELQ](/docs/accelq/)
- [SmartBear Reflect](/docs/reflect-run/)
- [UiPath](/docs/uipath/)
- [ReadyAPI](/docs/readyapi/)
- [Power Automate](/docs/power-automate/)
- [MuleSoft / Anypoint](/docs/mulesoft/)

## Additional example-first frameworks

- [Codeception example project](https://github.com/mailslurp/examples/tree/master/php-codeception-acceptance)
- [Vitest wait methods example](https://github.com/mailslurp/examples/tree/master/wait-for-methods-vitest)
- [Ruby Cucumber example project](https://github.com/mailslurp/examples/tree/master/ruby-cucumber-test)
- [Capybara + Cucumber + Selenium example](https://github.com/mailslurp/examples/tree/master/ruby-capybara-cucumber-selenium)
- [More examples](/docs/examples/)

## 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.

## Related docs

- [Deliverability tests](/docs/deliverability-test/)
- [Wait for methods](/docs/wait-for/)
- [Device previews](/docs/device-renders/)
- [Email audit](/docs/email-audit/)
- [MFA/TOTP devices](/docs/totp/)
