Django Test framework with file based Email backend server

Question:

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 ?

Asked By: Anuj

||

Answers:

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."
Answered By: Furbeenator

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
Answered By: Tim Edgar

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'
Answered By: Andrii Dubonos