unit testing a routine that sends mail

commander_coder commander_coder at hotmail.com
Thu Feb 18 15:37:27 CET 2010


Hello,

I have a routine that sends an email (this is how a Django view
notifies me that an event has happened).  I want to unit test that
routine.  So I gave each mail a unique subject line and I want to use
python's mailbox package to look for that subject.  But sometimes the
mail gets delivered and sometimes it does not (I use sendmail to send
it but I believe that it is always sent since I can see an entry in
the mail log).

I thought that the mail delivery system was occasionally hitting my
mailbox lock, and that I needed to first sleep for a while.  So I
wrote a test that sleeps, then grabs the mailbox and looks through it,
and if the mail is not there then it sleeps again, etc., for up to ten
tries.  It is below.

However, I find that if the mail is not delivered on the first try
then it is never delivered, no matter how long I wait.  So I think I
am doing mailbox wrong but I don't see how.

The real puzzler for me is that the test reliably fails every third
time.  For instance, if I try it six times then it succeeds the first,
second, fourth, and fifth times.  I have to say that I cannot
understand this at all but it certainly makes the unit test useless.

I'm using Python 2.6 on an Ubuntu system.  If anyone could give me a
pointer to why the mail is not delivered, I sure could use it.

Thanks,
Jim

...................................................................

class sendEmail_test(unittest.TestCase):
    """Test sendEmail()
    """
    config = ConfigParser.ConfigParser()
    config.read(CONFIG_FN)
    mailbox_fn=config.get('testing','mailbox')

    def look_in_mailbox(self,uniquifier='123456789'):
        """If the mailbox has a message whose subject line contains
the
        given uniquifier then it returns that message and deletes it.
        Otherwise, returns None.
        """
        sleep_time=10.0  # wait for message to be delivered?
        message_found=None
        i=0
        while i<10 and not(message_found):
            time.sleep(sleep_time)
            m=mailbox.mbox(self.mailbox_fn)
            try:
                m.lock()
            except Exception, err:
                print "trouble locking the mailbox: "+str(err)
            try:
                for key,message in m.items():
                    subject=message['Subject'] or ''
                    print "subject is ",subject
                    if subject.find(uniquifier)>-1:
                        print "+++found the message+++ i=",str(i)
                        message_found=message
                        m.remove(key)
                        break
                m.flush()
            except Exception, err:
                print "trouble reading from the mailbox: "+str(err)
                m.unlock()
            try:
                m.unlock()
            except Exception, err:
                print "trouble unlocking the mailbox: "+str(err)
            try:
                m.close()
            except Exception, err:
                print "trouble closing the mailbox: "+str(err)
            del m
            i+=1
        return message_found

    def test_mailbox(self):
        random.seed()
        uniquifier=str(int(random.getrandbits(20)))
        print "uniquifier is ",uniquifier  # looks different every
time to me
        rc=az_view.sendEmail(uniquifier=uniquifier)
        if rc:
            self.fail('rc is not None: '+str(rc))
        found=self.look_in_mailbox(uniquifier)
        if not(found):
            self.fail('message not found')
        print "done"



More information about the Python-list mailing list