[Tutor] Writing unit tests that involve email
Arnel Legaspi
jalespring at gmail.com
Wed Jul 17 07:14:28 CEST 2013
Steven D'Aprano <steve <at> pearwood.info> writes:
>
> On 17/07/13 13:34, Arnel Legaspi wrote:
>
> > the trouble I have is on making the unit tests run such that
> > it
> > will force the script I'm testing to send the email. If I just use the
> > script
> > on my own, it does send the emails, no problem. With the unit tests I've
> > written, it's not doing so.
>
> How does your script send emails? At some place, there will be something
> that effectively does the following steps:
>
> * build email
> * send email
>
> I recommend that your script has a function that does each: somewhere you
> have something that says
>
> def build_email_body(arg1, arg2, arg3):
> ...
>
> def send_email(body):
> ...
>
> Then you can test each separately. In your unit tests, you just call
> build_email_body and sees if it returns the correct data, no sending
> required; and then you call send_email and see that it actually sends an
> email.
The script does have a send_post() function that essentially builds the
email
message itself, along with the necessary headers, and runs the
smtplib.SMTP_SSL() method to send the whole thing off to the SMTP server.
Should I factor each component out of the send_post() function to test for
them
separately, or just leave it as is? Is it better to do so?
> Oh, all of this assumes that the unit test imports your script! This makes
> it critical that your script includes something like this at the end:
>
> def run(): # or "main", if you prefer
> # script logic goes in here
>
> if __name__ == '__main__':
> run()
>
> Then your tests can import the script without it automatically running.
So it does come down to importing the script methods *inside* the unit
tests. I
thought it was done otherwise.
In the unit tests, I have methods that clears the arguments given to the
script
(clear_args()) and replaces them with the ones created by the setUp() method
(add_testfiles()). I do have a run() function which gets the arguments, and
runs the send_post() function.
I guess I'll have to try and see whether it's enough for the script to run
with
the unit-test-supplied arguments and probably just add something like:
import downpost
...
class TestReadingSendingPostFile(unittest.TestCase):
def setUp():
...
def test_sendpost(self):
clear_args()
add_testfiles()
downpost.run()
All right, Steven. Thanks for the nudge in the right direction!
--Arnel
More information about the Tutor
mailing list