假设电子邮件实现与本文中接受的答案一样简单,那么为实现编写单元测试的最佳方法是什么?(作为测试实施的一部分,我不想向有效的收件人发送电子邮件)
2 回答
首先,您可以粗略地将单元测试称为您所描述的内容。单元测试通常是指测试尽可能小的代码片段(没有任何网络活动和 I/O 支持)。
因此,您可以编写一个单元测试来使用模拟和存根测试消息发送单元,而无需通过网络发送实际消息。使用 mock 模拟不同方式的消息发送结果:
- 消息发送正确
- 发送消息时收到超时
- 延迟发送的消息
您谈论的案例通常称为集成测试,当您测试应用程序不同部分之间的交互时,在您的案例中:邮件服务器和消息发送者。
因此,要测试您可以执行以下操作:
以下是 poplib 工作原理的示例:
import getpass, poplib
M = poplib.POP3('localhost')
M.user(getpass.getuser()) # Assuming that mailbox has your OS user/pass
M.pass_(getpass.getpass())
numMessages = len(M.list()[1])
for i in range(numMessages):
for j in M.retr(i+1)[1]:
print j
这是一个如何使用poplib检索消息的示例(无耻地取自 poplib 的官方文档)。同样,您可以使用imaplib。这取决于您的邮件服务器支持哪些技术。
笔记!您必须记住,编写测试并不总是那么简单。您的代码必须适合单元测试,例如,当您想测试邮件发送时,您的发送函数/类必须使用消息发送对象(在我们的例子中为 SMTP)调用/初始化,在测试期间可以模拟(用模拟对象替换) .
首先,使负责发送/接收的部分可插拔。只需确保您可以切换负责将消息连接/发送/接收到/从服务器的类/函数/对象。
其次,使这部分成为真实的东西。确保这个类/函数/对象将尽可能接近原始类/函数/对象的行为(采用相同的参数,抛出相同的错误)。
第三,在测试中伪造这部分的不同行为。此类在不同测试中的不同行为可能包括:
- 正确发送,
- 延迟发送,
- 连接超时,
- 接收成功,
并且,根据您的模块的实际用途(以及它的灵活性,例如,如果它可以被其他人用于编码),您还可以包括以下行为:
- 传递错误参数时出错,
- 在这里发现了广泛的其他例外:http: //docs.python.org/library/smtplib.html
这在很大程度上取决于您的模块的功能。您需要测试它是否正确执行这些操作。不要测试smtplib
模块,因为它已经被测试覆盖了。不要测试与你的模块无关的东西——只测试它所做的事情。您的模块的某些部分可能是不可测试的——在这种情况下,您有两个选择:将它们更改为可测试,或者保持原样(由于各种原因,它有时是最合理的选择)。