1

I'm using Django 1.9 and django.test for my unit test.

This is my code for testing signals:

@receiver(post_save, sender=EmailNotification, dispatch_uid="spacegraphy")
def post_save_notification(sender, instance, created, **kwargs):
    if created:
        if settings.DEBUG:
            print("post_save: created!!!")
        else:
            instance.send_notification()

When I run this application in local, it run as development mode, which shows print(settings.DEBUG) as True. (I checked it in shell_plus of django-extension

However, when I test my unit tests, print(settings.DEBUG) show False.

I have no idea why it happened. Any idea, please?

jape
  • 2,861
  • 2
  • 26
  • 58
user3595632
  • 5,380
  • 10
  • 55
  • 111
  • This is not your code for 'testing' signals, this is application logic that you want to test (if I understand correctly). At the moment you're trying to detect the testing condition in the application logic so that you can avoid real world side effects of your code, but if you follow that path you'll end up with messy unmaintainable code. That's what mocking is for. – ChidG Jan 06 '17 at 01:46
  • @ChidG mocking in application logic? ... – user3595632 Jan 06 '17 at 05:05
  • @ user3595632 no, perhaps I wasn't clear enough. I meant mocking in tests, which should be entirely separated from the application logic. – ChidG Jan 06 '17 at 05:58
  • Let say there is a slack notification when newly signup comes up. In development mode, I might have a case I have to sign up for some reason. In this case, it would send slack notification, too, which I don't want to. – user3595632 Jan 06 '17 at 07:29
  • Sure, that's reasonable, but there may be a form of 'mocking' you could do there - for instance use a 'test' slack instance to post to, which is defined in the project settings. You could use a similar pattern for testing. How you structure that is up to you, but you're right that there are some cases where it's valid to check `DEBUG` status in your code. I don't think it's wise to use it a lot. Maybe you should check out how Django handles email - ie using different backends for development/testing and for production - and follow a similar pattern. – ChidG Jan 06 '17 at 08:18
  • did you try my answer? Mocking I think would be overkill for this – e4c5 Jan 09 '17 at 12:41

1 Answers1

2

From https://docs.djangoproject.com/en/1.10/topics/testing/overview/#other-test-conditions:

Regardless of the value of the DEBUG setting in your configuration file, all Django tests run with DEBUG=False. This is to ensure that the observed output of your code matches what will be seen in a production setting.

I would suggest you write your test differently. The purpose is to test the functionality of the code as it would run in production, so there should be no need to check the value of DEBUG.

ChidG
  • 3,053
  • 1
  • 21
  • 26
  • The reason I need to separate mode : I have a function to send slack notifications in my Django application. But I don't want to send notification message in test and development mode. Do I have to mock the signal in test, then? – user3595632 Jan 06 '17 at 01:25
  • Yeah, mocking would be the usual way of doing it. I found this page to be a really good explanation of mocking in similar situations https://www.obeythetestinggoat.com/book/chapter_16.html – ChidG Jan 06 '17 at 01:31