Django Test framework with file based Email backend server
Asked Answered
T

3

9

I have formulated test cases in Django framework.

Use Case: I am using API that register user by sending them an Email and when they click on the link provided in the Email their account get activated.

In my settings.py I am using

EMAIL_FILE_PATH  ='django.core.mail.backends.filebased.EmailBackend'

which points to the local directory.

When running PyUnit test case from eclipse everything works file. Text file gets generated for each email sent

But, When i am using

python ./manage.py test <component_name>

the files does not generate.

Any insight what is the difference when I execute test case with ./manage.py and when I use pyUnit ?

Two answered 12/12, 2012 at 21:26 Comment(1)
When you use manage.py test, all email functionality is redirected to the dummy outbox, meaning nothing gets done, NO MATTER what your email backend settings are in settings.py. They assume you don't want to send real email or create files in your real-world environment when testing.Wilone
W
7

The simple answer:

You can't do this without engineering your own email system, but that would probably be silly. I would suggest doing something else to verify that the code was successful without requiring the email to be sent. Like, run the code, assume the user clicks the link and create RequestFactory to get/post the link to run the view code associated with it.

From the Django Testing Application:

Email services

"If any of your Django views send email using Django's email functionality,
you probably don't want to send email each time you run a test using that
view. For this reason, Django's test runner automatically redirects all
Django-sent email to a dummy outbox. This lets you test every aspect of
sending email -- from the number of messages sent to the contents of each
message -- without actually sending the messages."
Wilone answered 12/12, 2012 at 21:32 Comment(0)
O
38

It's possible to overwrite this aspect in Django if you want to use a specific email backend.

In django.test.utils, Django will change the e-mail backend to locmem as mentioned in the Django Testing documentation when Django sets up the testing environment:

def setup_test_environment():
...
    mail.original_email_backend = settings.EMAIL_BACKEND
    settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'

So if you want to enable sending e-mails for a test, you just need to change the setting to what you want.

from django.test.utils import override_settings

@override_settings(EMAIL_BACKEND='django.core.mail.backends.filebased.EmailBackend')
class MyTest(TestCase):
    # your test case
Oberhausen answered 24/2, 2013 at 16:43 Comment(0)
W
7

The simple answer:

You can't do this without engineering your own email system, but that would probably be silly. I would suggest doing something else to verify that the code was successful without requiring the email to be sent. Like, run the code, assume the user clicks the link and create RequestFactory to get/post the link to run the view code associated with it.

From the Django Testing Application:

Email services

"If any of your Django views send email using Django's email functionality,
you probably don't want to send email each time you run a test using that
view. For this reason, Django's test runner automatically redirects all
Django-sent email to a dummy outbox. This lets you test every aspect of
sending email -- from the number of messages sent to the contents of each
message -- without actually sending the messages."
Wilone answered 12/12, 2012 at 21:32 Comment(0)
P
0

For somebody (like me) that need to use custom email backend for all tests, another solution would be to override TestRunner class and force settings change.

from django.conf import settings
from django.test.runner import DiscoverRunner


class CustomTestRunner(DiscoverRunner):
    def setup_test_environment(self, **kwargs):
        super().setup_test_environment(**kwargs)
        settings.EMAIL_BACKEND = 'path.to.your.email.backend'

And after that register the test runner in settings:

TEST_RUNNER = 'path.to.CustomTestRunner'
Planetary answered 12/9, 2022 at 7:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.