Django Email Testing
Django Email Testing
Idea: In tests, Django can use an in-memory backend so nothing is really sent. All “sent” emails go to mail.outbox (a list).
- Test settings:
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'(or leave default in tests; many setups use locmem). Thenfrom django.core import mailand assert onmail.outbox. - Assert:
len(mail.outbox) == 1,mail.outbox[0].subject,mail.outbox[0].to,mail.outbox[0].body. For HTML:mail.outbox[0].alternatives. - Views that send email: Call the view (e.g. post to register), then assert outbox. No sleep — with locmem it’s synchronous.
- Templates: Render with
render_to_string('emails/welcome.html', context)and assert content, or send and assert body/alternatives. - Celery tasks that send email: Use
CELERY_ALWAYS_EAGER=Truein tests so the task runs inline, then checkmail.outbox. Or mocksend_mailand assert it was called with the right args.
Avoid: time.sleep() to “wait” for email. Use the right backend and/or EAGER so everything is immediate.
Clear outbox between tests: mail.outbox is usually cleared per test; if not, mail.outbox.clear() in setUp.