5

I have a lot of unit tests in Django and if a test fails, I often need to see the logs (in the console, if possible). I can't really use the log file because it gets really messy.
What I do right now is: activate console logging in the settings.py, and only run one specific test. I was hoping that there is a more convenient way to do it. I only want to see what was being logged for the failing tests and not the complete log.

Edit: even though an answer was posted — and I have accepted it — I'm not quite content. I want to see only the logging output of failing tests. I was looking for a solution like that which PHPUnit provides. It captures the complete output (for logging + print) and only writes it to stdout if the test fails.

Matt3o12
  • 4,192
  • 6
  • 32
  • 47
  • Are you adding some "print"s in the code? – brunofitas Jun 29 '14 at 13:26
  • @brunofitas No, I use python's log module. – Matt3o12 Jun 29 '14 at 13:29
  • I usually use the "print" command and it works fine when running locally. The prints and the errors are displayed on the server window and usually I don't need anything else. – brunofitas Jun 29 '14 at 13:35
  • @brunofitas Well, if I used prints in my code all the time, I would see the output of these prints for all unit tests as well. In addition, prints are thrown away by MOD_WSGI, so, I can't switch to print statements. I wound't also be able to capture the SQL log that way (which can also be very helpful). – Matt3o12 Jun 29 '14 at 13:45

3 Answers3

1

Set the root logger to use the console handler only when running tests. Easiest way to detect is to see if "test" is the second argv parameter. Make sure all interesting loggers have "propagate": True so that they forward their logs to the root logger.

# settings.py
import sys

if sys.argv[1] == 'test':
    LOGGING['root'] = {
        'handlers': ['console'],
        'level': 'DEBUG',
    }
Thomas
  • 11,757
  • 4
  • 41
  • 57
  • 1
    That actives logging for all test. But I only want to see the log for all failing tests. Using this code, I get way too much log output and I can hardly see which logs fail. – Matt3o12 Jun 30 '14 at 09:40
  • So, just rerun the failing tests and record log output. – Thomas Jun 30 '14 at 10:15
1

Well, I just figured out how to fix it.
Apparently there is a -b option that "buffers the output" unless the test fails when running a unit tests. It is very easy to use if your tests.py file executes unittest.main(). Just type python tests.py -b and the complete output will be buffered unless the test fails.

...........F
Stdout:
OK :)
OK :)

======================================================================
FAIL: testStr (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests.py", line 93, in testStr
    self.fail()
AssertionError: None

Stdout:
OK :)
OK :)

----------------------------------------------------------------------
Ran 12 tests in 0.005s

In this case, every test printed something to stdout but only the very last one (the failing one was shown). Since the log can also be printed to the console (see @Thomas's answer), you will only see relevant logs.

Matt3o12
  • 4,192
  • 6
  • 32
  • 47
0

The quick and dirty way to access your log output on the console is to monkey patch logging.. To overwrite logging.info for example:

def monkey_print(*args):
   print args
setattr(logging, 'info', monkey_print)

Then just delete it when you're done. Quick and dirty. It works with unittest too.

joel3000
  • 1,249
  • 11
  • 22