I am using PyDev for development and unit-testing of my Python application. As for unit-testing, everything works great behalf the fact that content logged to any logging. Logger is not captured by the "Captured output" of PyDev.
I already forward everything logged to the standard output like this:
import sys
logger = logging.getLogger()
logger.level = logging.DEBUG
logger.addHandler(logging.StreamHandler(sys.stdout))
Nevertheless the "Captured output" does not display stuff logged to loggers.
Here an example unittest-script: test.py
import sys
import unittest
import logging
logger = logging.getLogger()
logger.level = logging.DEBUG
logger.addHandler(logging.StreamHandler(sys.stdout))
class TestCase(unittest.TestCase):
def testSimpleMsg(self):
print("AA")
logging.getLogger().info("BB")
The console output is:
Finding files... done.
Importing test modules ... done.
testSimpleMsg (itf.lowlevel.tests.hl7.TestCase) ... AA
2011-09-19 16:48:00,755 - root - INFO - BB
BB
ok
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
But the CAPTURED OUTPUT for the test is:
======================== CAPTURED OUTPUT =========================
AA
Does anybody knows how to capture everything is logged to a logging.Logger
during the execution of this test?
The issue is that the
unittest
runner replacessys.stdout
/sys.stderr
before the testing starts, and theStreamHandler
is still writing to the originalsys.stdout
.If you assign the 'current'
sys.stdout
to the handler, it should work (see the code below).Although, a better approach would be adding/removing the handler during the test:
I grew tired of having to manually add Fabio's great code to all
setUp
s, so I subclassedunittest.TestCase
with some__metaclass__
ing:Now your test case can simply inherit from
LoggedTestCase
, i.e.class TestCase(LoggedTestCase)
instead ofclass TestCase(unittest.TestCase)
and you're done. Alternatively, you can add the__metaclass__
line and define thelogger
either in the test or a slightly modifiedLogThisTestCase
.I came across this problem also. I ended up subclassing StreamHandler, and overriding the stream attribute with a property that gets sys.stdout. That way, the handler will use the stream that the unittest.TestCase has swapped into sys.stdout:
You can then setup the logging handler before running tests like so (this will add the custom handler to the root logger):
If, like me, you have your tests in separate modules, you can just put a line after the imports of each unit test module that will make sure the logging is setup before tests are run:
This might not be the cleanest approach, but it's pretty simple and worked well for me.
I'd suggest using a LogCapture and testing that you really are logging what you expect to be logging:
http://testfixtures.readthedocs.org/en/latest/logging.html