django - how to detect test environment (check / determine if tests are being run)

前端 未结 8 836
长情又很酷
长情又很酷 2020-12-07 20:40

How can I detect whether a view is being called in a test environment (e.g., from manage.py test)?

#pseudo_code
def my_view(request):
    if not          


        
相关标签:
8条回答
  • 2020-12-07 21:05

    Put this in your settings.py:

    import sys
    
    TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'
    

    This tests whether the second commandline argument (after ./manage.py) was test. Then you can access this variable from other modules, like so:

    from django.conf import settings
    
    if settings.TESTING:
        ...
    

    There are good reasons to do this: suppose you're accessing some backend service, other than Django's models and DB connections. Then you might need to know when to call the production service vs. the test service.

    0 讨论(0)
  • 2020-12-07 21:10

    Piggybacking off of @Tobia's answer, I think it is better implemented in settings.py like this:

    import sys
    try:
        TESTING = 'test' == sys.argv[1]
    except IndexError:
        TESTING = False
    

    This will prevent it from catching things like ./manage.py loaddata test.json or ./manage.py i_am_not_running_a_test

    0 讨论(0)
  • 2020-12-07 21:11

    There's also a way to temporarily overwrite settings in a unit test in Django. This might be a easier/cleaner solution for certain cases.

    You can do this inside a test:

    with self.settings(MY_SETTING='my_value'):
        # test code
    

    Or add it as a decorator on the test method:

    @override_settings(MY_SETTING='my_value')
    def test_my_test(self):
        # test code
    

    You can also set the decorator for the whole test case class:

    @override_settings(MY_SETTING='my_value')
    class MyTestCase(TestCase):
        # test methods
    

    For more info check the Django docs: https://docs.djangoproject.com/en/1.11/topics/testing/tools/#django.test.override_settings

    0 讨论(0)
  • 2020-12-07 21:13

    If you are multiple settings file for different environment, all you need to do is to create one settings file for testing.

    For instance, your setting files are:

    your_project/
          |_ settings/
               |_ __init__.py
               |_ base.py  <-- your original settings
               |_ testing.py  <-- for testing only
    

    In your testing.py, add a TESTING flag:

    from .base import *
    
    TESTING = True
    

    In your application, you can access settings.TESTING to check if you're in testing environment.

    To run tests, use:

    python manage.py test --settings your_project.settings.testing
    
    0 讨论(0)
  • 2020-12-07 21:14

    Just look at request.META['SERVER_NAME']

    def my_view(request):
        if request.META['SERVER_NAME'] == "testserver":
            print "This is test environment!"
    
    0 讨论(0)
  • 2020-12-07 21:17

    While there's no official way to see whether we're in a test environment, django actually leaves some clues for us. By default Django’s test runner automatically redirects all Django-sent email to a dummy outbox. This is accomplished by replacing EMAIL_BACKEND in a function called setup_test_environment, which in turn is called by a method of DiscoverRunner. So, we can check whether settings.EMAIL_BACKEND is set to 'django.core.mail.backends.locmem.EmailBackend'. That mean we're in a test environment.

    A less hacky solution would be following the devs lead by adding our own setting by subclassing DisoverRunner and then overriding setup_test_environment method.

    0 讨论(0)
提交回复
热议问题