Testing Email Workflows Without Email Server — With Playwright & Mokapi

Testing Email Workflows Without Email Server — With Playwright & Mokapi

无需邮件服务器即可测试邮件工作流 — 使用 Playwright 和 Mokapi

Email is one of those things that’s genuinely hard to test. It goes out through an SMTP server, lands in a real inbox, and you have no programmatic way to check what arrived. So most teams either test it manually or just assert that sendEmail() was called and call it done. Neither tells you if the subject line was right, the link was valid, or the HTML rendered correctly.

电子邮件是那种真正难以测试的事物之一。它通过 SMTP 服务器发送,到达真实的收件箱,而你没有程序化的方法来检查收到了什么。因此,大多数团队要么手动测试,要么仅仅断言 sendEmail() 已被调用就草草了事。这两种方法都无法告诉你主题行是否正确、链接是否有效,或者 HTML 是否渲染正确。

That’s why I built email support into Mokapi. Your backend connects to Mokapi’s SMTP server exactly as it would a real mail server. Mokapi captures the message. Your test fetches it over HTTP and asserts on the content. No real emails, no inbox polling, no external dependencies.

这就是我将邮件支持集成到 Mokapi 中的原因。你的后端连接到 Mokapi 的 SMTP 服务器,方式与连接真实邮件服务器完全相同。Mokapi 会捕获这些消息,你的测试程序通过 HTTP 获取它们并对内容进行断言。无需真实邮件,无需轮询收件箱,也无需外部依赖。

The Config

配置

Unlike Kafka or HTTP, email doesn’t have a standard specification format. So Mokapi uses a simple YAML config. This is all you need:

与 Kafka 或 HTTP 不同,电子邮件没有标准的规范格式。因此,Mokapi 使用简单的 YAML 配置。你只需要这些:

mail: '1.0'
info:
  title: "Email Workflows"
servers:
  smtp:
    host: :2525
    protocol: smtp

Point your backend at localhost:2525 and Mokapi starts capturing everything. Want IMAP too, so you can preview emails in a real mail client during development? Add one line:

将你的后端指向 localhost:2525,Mokapi 就会开始捕获所有内容。想要 IMAP 支持,以便在开发过程中在真实的邮件客户端中预览邮件吗?只需添加一行:

  imap:
    host: :1430
    protocol: imap

The Playwright Test

Playwright 测试

The test drives a real signup form, then fetches the captured email from Mokapi’s HTTP API and asserts on it.

该测试驱动一个真实的注册表单,然后从 Mokapi 的 HTTP API 获取捕获的邮件并对其进行断言。

test('Email verification after signup', async ({ page, request }) => {
  const recipient = randomEmail();
  
  // Drive the signup form
  await page.goto('');
  const form = page.getByRole('form', { name: 'Sign Up' });
  await form.getByLabel('Email').fill(recipient);
  await form.getByLabel('Password').fill('SuperSecure123!');
  await form.getByRole('button', { name: 'Sign Up' }).click();
  await expect(form.getByText('Check your inbox to verify your email')).toBeVisible();

  // Fetch the email from Mokapi
  const mails = await request.get(
    `http://localhost:8080/api/services/mail/Email%20Workflows/mailboxes/${recipient}/messages?limit=1`
  );
  const mailList = await mails.json();
  expect(mailList[0]).toEqual(expect.objectContaining({
    subject: 'Verify your email address',
    from: expect.arrayContaining([expect.objectContaining({ address: 'noreply@example.com' })]),
    to: expect.arrayContaining([expect.objectContaining({ address: recipient })])
  }));

  // Check the body and verification link
  const res = await request.get(
    `http://localhost:8080/api/services/mail/messages/${mailList[0].messageId}`
  );
  const mail = await res.json();
  expect(mail.body).toContain(`verify?email=${encodeURIComponent(recipient)}`);
});

Random email per test run keeps things isolated. Playwright’s request object handles the Mokapi API calls directly, so the same test that drives the browser also inspects the email. No extra HTTP client needed.

每次测试运行使用随机邮箱可以保持测试的独立性。Playwright 的 request 对象直接处理 Mokapi API 调用,因此驱动浏览器的同一个测试也可以检查邮件。无需额外的 HTTP 客户端。

The IMAP Bonus

IMAP 额外福利

Automated assertions catch broken content. But they don’t catch a layout that looks terrible in Outlook. Because Mokapi supports IMAP, you can connect any real mail client to localhost:1430 during development and see exactly what your users will see. It’s the visual check your test suite can’t do.

自动化断言可以捕获损坏的内容,但无法捕获在 Outlook 中看起来很糟糕的布局。由于 Mokapi 支持 IMAP,你可以在开发过程中将任何真实的邮件客户端连接到 localhost:1430,并准确查看用户将看到的内容。这是你的测试套件无法完成的视觉检查。

Full Walkthrough

完整指南

This is the short version. The complete guide on my site covers the full config, the Express backend, all the Playwright helpers, and how it all fits together.

以上是简短版本。我网站上的完整指南涵盖了完整的配置、Express 后端、所有的 Playwright 辅助工具以及它们是如何整合在一起的。

👉 Read the full guide here 👉 点击此处阅读完整指南

Working repo: mokapi-email-workflow 工作仓库:mokapi-email-workflow

Happy to answer questions in the comments. 欢迎在评论区提问。