Reputation: 9794
Assuming an email implementation as simple as the accepted answer on this post, what can be the best way to write a unit test for the implementation? (I do not want to shoot emails to a valid recipient as part of testing the implementation)
Upvotes: 3
Views: 5142
Reputation: 40765
First of all, you can roughly call a unit test something you've described. Unit test usually refers to testing as small pieces of code as possible (without any network activity and I/O support).
So you can write a unittest to test message sending unit using mocks and stubs without actual message sending over network. Use mock to emulate different ways of message sending results:
The case you're talking about is usually referred to as integration testing, when you test interaction between different parts of your application, in your case: mail server and message sender.
So to test that you can do the next:
Here's an example of how poplib works:
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
This is an example of how to retrieve message using poplib (shamelessly taken from official documentation of poplib). Similarly you can use imaplib. It depends on what technologies does your mail server support.
Note! You must remember that writing test is not always that simple. Your code must be adapted for unittesting, e.g. when you want to test mail sending, your sender function/class must be called/initialized with message sending object (SMTP in our case), that can be emulated (replaced with mock object) during testing.
Upvotes: 3
Reputation: 137370
First, make the part responsible for sending / receiving pluggable. Just make sure you can switch the class / function / object responsible for connecting / sending / receiving messages to / from the server.
Second, make this part act as real thing. Make sure this class / function / object will fake original class's / function's / object's behaviour as close as possible (take the same parameters, throw the same errors).
Third, fake different behaviours of this part during tests. Different behaviours of this class in different tests may include:
and, depending on what your module really does (and how flexible it is, eg. if it can be used by someone else for coding), you can also include these behaviours:
It really largely depends on what your module does. You need to test, if it does these things properly. Do not test smtplib
module, as it is already covered with tests. Do not test things irrelevant to your module - just things it does. It is possible, that some parts of your modules are untestable - in that case you have two options: change them to be testable, or leave them as they are (it is sometimes the most reasonable option for various reasons).
Upvotes: 3