所有文章 > API使用场景 > 使用smtp4dev API自动化SMTP电子邮件服务器测试

使用smtp4dev API自动化SMTP电子邮件服务器测试

在本文中,我们将探讨smtp4dev提供的一系列API,这些API能够帮助我们自动化测试流程!

官方提供的API文档解释不足,需要花费了不少时间才弄清楚每个API的具体功能以及它们各自的用途。

在此,我将分享这些API的详细信息,包括你可能需要使用这些API的测试场景,希望这样能帮助你们避免我之前所经历的困扰!

先决条件

本文假设你已经安装并启动了你的模拟服务器。

启动你的服务器,我们这就开始吧!

首先,你可以通过访问 http://localhost:5000/api 来获取OpenAPI文档。

遗憾的是,文档中并没有对每个API的具体功能进行描述(这就是我们在这里的原因)!(还有,为什么会有人在URL中使用大写字母!)

设置服务器

在开始从你的应用程序发送电子邮件之前,你可能需要配置几件事情,即用户和邮箱。

用户允许你进行身份验证,而邮箱是你设置收件人的地方,最终也是你检查收到的邮件的地方。

为此,我们将使用POST请求 http://localhost:5000/api/Server。然而,所需的请求体包含许多你可能想要保留为默认值的参数。

以下是我处理这个问题的方法。首先,使用GET请求 http://localhost:5000/api/Server,以便我们获取当前的服务器设置。响应将如下所示。

{
"settingsAreEditable": true,
"lockedSettings": {},
"isRunning": true,
"exception": null,
"port": 25,
"hostName": "EC2AMAZ-FG4OBNC",
"allowRemoteConnections": true,
"numberOfMessagesToKeep": 100,
"numberOfSessionsToKeep": 100,
"imapPort": 143,
"disableMessageSanitisation": false,
"tlsMode": "None",
"authenticationRequired": false,
"credentialsValidationExpression": "",
"secureConnectionRequired": false,
"recipientValidationExpression": "",
"messageValidationExpression": "",
"disableIPv6": false,
"users": [],
"mailboxes": [
{
"name": "12@d.c",
"recipients": "12@d.c"
}
],
"relaySmtpServer": "",
"relaySmtpPort": 25,
"relayAutomaticEmails": [],
"relaySenderAddress": "",
"relayLogin": "",
"relayPassword": "",
"relayTlsMode": "None",
"relayAutomaticRelayExpression": "",
"webAuthenticationRequired": false,
"desktopMinimiseToTrayIcon": false,
"isDesktopApp": false,
"smtpAllowAnyCredentials": true,
"smtpEnabledAuthTypesWhenSecureConnection": [
"PLAIN",
"LOGIN",
"CRAM-MD5"
],
"smtpEnabledAuthTypesWhenNotSecureConnection": [
"PLAIN",
"LOGIN",
"CRAM-MD5"
],
"currentUserName": null,
"currentUserDefaultMailboxName": "Default"
}

然后,我们可以使用这个响应作为我们的POST请求体,并只修改我们想要更改的参数。例如,如果我们想要添加一个新的邮箱,名为 to@example.com,收件人为 to@example.com,我们只需要将mailboxes键更改为以下内容。

"mailboxes": [
{
"name": "12@d.c",
"recipients": "12@d.c"
},
{
"name": "to@example.com",
"recipients": "to@example.com"
}
]

获取所有邮箱

如果你想在测试中遍历所有的邮箱,你可以通过使用上述的GET /api/Server获取它们,或者你也可以使用GET http://localhost:5000/api/Mailboxes API。

这将返回一个邮箱列表,如下所示。

[
{
"id": "42588956-8078-49c2-b9a1-82bcc8fec9f4",
"name": "Default"
},
{
"id": "51251730-80c1-4fa3-8eeb-18afe848294b",
"name": "12@d.c"
},
{
"id": "1b4dff75-8490-485d-a6e5-a83493721bea",
"name": "to@example.com"
}
]

你需要邮箱的名称来获取其中的消息(如果它不是默认邮箱)。

获取所有电子邮件

现在我们已经为我们的收件人设置了邮箱,让我们从我们的应用程序发送一些电子邮件给它。

要获取目标邮箱中的所有消息,我们可以使用两个API。

GET http://localhost:5000/api/Messages GET http://localhost:5000/api/Messages/new 并设置查询参数mailboxName为目标邮箱的名称。

例如,如果我们想要获取发送到12@d.c的电子邮件,我们只需执行GET http://localhost:5000/api/Messages/new?mailboxName=12%40d.c。响应将如下所示。

[
{
"isRelayed": false,
"deliveredTo": "12@d.c",
"id": "32a199b9-bdc5-4dfd-9556-00486c0c9372",
"from": "from@example.com",
"to": [
"12@d.c"
],
"receivedDate": "2024-07-05T06:43:02.1692009Z",
"subject": "test2",
"attachmentCount": 0,
"isUnread": false
},
{
"isRelayed": false,
"deliveredTo": "12@d.c",
"id": "bfcaacb6-4e31-4897-8d86-b51e0a9dc329",
"from": "from@example.com",
"to": [
"12@d.c"
],
"receivedDate": "2024-07-05T03:33:33.9320652Z",
"subject": "test1",
"attachmentCount": 0,
"isUnread": false
}
]

你以为“/new”意味着只获取未读邮件?不是的!如果你只对未读消息感兴趣,你得自己检查isUnread字段!

那么“/new”是什么意思呢?这只是我的猜测,但我认为它允许你指定lastSeenMessageId,这样任何在那之前的消息(包括那条消息)都不会被包含在内。

你应该使用哪一个?如果你想要基于最后一条消息ID来过滤消息,或者不需要其他类型的排序或过滤,使用/Messages/new。

如果你想要设置排序顺序或使用特定的搜索词查询,使用/Messages。对我来说,这两个API是可以互换的。

获取电子邮件内容

现在我们已经得到了电子邮件(或者你称之为消息)的ID,我们准备获取它的正文了!

分为两步。

  1. 使用GET http://localhost:5000/api/Messages/{id}获取电子邮件的所有部分。
  2. 遍历这些部分,并通过GET http://localhost:5000/api/Messages/{id}/part/{part_id}/content获取每个部分的内容。

让我们更详细地看看这个过程。

首先,我们将使用Messages/{id}来获取我们电子邮件的结构。在响应中,除了部分内容外,还有其他信息,比如头部信息。

{
"sessionEncoding": "iso-8859-1",
"eightBitTransport": null,
"hasHtmlBody": false,
"hasPlainTextBody": true,
"id": "32a199b9-bdc5-4dfd-9556-00486c0c9372",
"from": "...",
"to": [
"\"123\" <12@d.c>"
],
"cc": [],
"bcc": [],
"deliveredTo": [
"12@d.c"
],
"receivedDate": "2024-07-05T06:43:02.1692009Z",
"secureConnection": false,
"subject": "test2",
"parts": [
{
"id": "0",
"headers": [
{
"name": "Content-Type",
"value": "text/plain; charset=UTF-8"
},
{
"name": "Content-Transfer-Encoding",
"value": "base64"
}
],
"childParts": [],
"name": "0 - text/plain",
"messageId": "32a199b9-bdc5-4dfd-9556-00486c0c9372",
"contentId": null,
"attachments": [],
"warnings": [],
"size": 894,
"isAttachment": false
}
],
"headers": [
{
"name": "Date",
"value": "Fri, 5 Jul 2024 15:43:01 +0900 (JST)"
},
{
"name": "From",
"value": "..."
},
{
"name": "To",
"value": "123 <12@d.c>"
},
{
"name": "Message-ID",
"value": "<1922961261.6.1720161781968@localhost>"
},
{
"name": "Subject",
"value": "test2"
},
{
"name": "MIME-Version",
"value": "1.0"
},
{
"name": "X-Mailer",
"value": "ColdFusion 2018 Application Server"
}
],
"mimeParseError": null,
"relayError": ""
}

然后,我们将遍历parts数组,并使用GET请求/Messages/{id}/part/{part_id}/content。这里的part_id将是parts数组中的id键。

part_id = 0为例:GET http://localhost:5000/api/Messages/32a199b9-bdc5-4dfd-9556-00486c0c9372/part/0/content,这是我们得到响应的内容。

Some body string

标记邮件为已读

由于我们只对获取未读邮件的内容感兴趣,因此以下做法是个好习惯:

在从应用程序发送任何内容之前,将所有邮件标记为已读(以防万一),
在我们获取了邮件内容之后,将该邮件标记为已读。

要将单个邮箱中的所有邮件标记为已读,我们将使用POST请求http://localhost:5000/api/Messages/markAllRead,并设置查询参数mailboxName为目标邮箱名称。

而要将单个邮件标记为已读,我们可以调用POST请求http://localhost:5000/api/Messages/{id}/markRead。注意,在这种情况下不需要查询参数mailboxName

如何找到更多同类API?

幂简集成是国内领先的API集成管理平台,专注于为开发者提供全面、高效、易用的API集成解决方案。幂简API平台可以通过以下两种方式找到所需API:通过关键词搜索API、或者从API Hub分类页进入寻找。

原文链接:https://blog.stackademic.com/use-smtp4dev-api-for-automate-smtp-email-server-testing-0faa45744a97