I’m working on two webapps that need to send email to users, and in both, the user is expected to click on a URL to confirm their registration. A common enough idiom for website accounts.
As a disciple of the cult of test-driven development, I want to be able to make a test that generates that email, inspects the contents for the URL, visits that generated URL, and then checks that the registration is completed.
Michael K, who previously suggested other abuses of Python’s dynamic nature, reminded me a few months ago that you could monkeypatch an imported library with your own, and it’d be preserved throughout the “address space” of the running Python program.
I’d not really played with it, and had been putting off writing a test
for email because I didn’t really understand what I wanted. The other
night at DebSIG, I asked (complained?) again about it, and he said
paste.fixture already does it!” I’d said I knew, but it had
no documentation, and no-one on the paste users list had responded to
my request for examples. He gave me a curt “Read the fucking source”
response (in a much nicer way of course) and I thought, he’s right!
Back in the day I used to read library source code in order to work
out poorly documented APIs, why now do I rely on clear documentation
so much? I should just dig in and write some example code to test it
out, and JFDI.
Enough of the backstory.
Here’s a quick guide to setting up an email sender test, using
paste.fixture around your Pylons application.
Firstly, in your controller, you have something that sends email, like so:
Pretty basic, if we visit
/foo/ then we send an email, and then if we visit
/foo/activate/N we inform the visitor of the activation.
The test is pretty simple too:
You just call the classmethod
Dummy_smtplib to set it up, which does some magic behind the scenes (really it just replaces
smtplib.SMTP with itself)
then run through the process you want to test
and now we check that the message was sent, and its contents
and finally, test the result of the activation.
You’ve also got to clean up, reset the dummy SMTP library for next time (you’ll get an exception thrown if you don’t, to remind you).
If you do any database stuff, then the times to check the status of the data model are just before the actuvation URL is visited, and again afterwards. I keep the model empty for each test, so I can pull out all the records and make sure that there’s only one afterwards, and that it has the right attributes before and after.
Pretty easy stuff.