How can one use the logging module in python with the unittest module?
I would like to use the python logging module to log all of the output from unittest so that I can incorporate it into a testing framework I am trying to write. The goal of this is to run the tests with 2 sets of output, one with simple output that tells the test case steps and a more debug level output so that when things go wrong we have as much info as possible. The output would be placed into two 开发者_运维问答files, one that I could email out to people, and another kept in case of failures. I noticed that the TextTestRunner can use a stream, could this be used with the logging module? I'm planning on using some of the new features in python 2.7.
You could, but I'm not sure it's your best approach.
For this approach, you would:
Instantiate an in-memory stream that can be used by
TextTestRunner
. This is the sort of thingio.StringIO
would be nearly perfect for, except that it works with Unicode input only, and I'm not sure that TextTestRunner writes Unicode properly to the stream. Your other option would be to code up your own in-memory stream that serves your purpose, perhaps wrappingStringIO
with an encoder.Create your own TextTestRunner and initialize it with this in-memory stream.
Create a class that reads from the stream and writes it to the log.
This could be as simple as:
class StreamLogger(object):
def __init__(self, input_stream, output_logger):
self.input_stream = input_stream
self.output_logger
def run(self):
while True:
line = input_stream.readline()
if not line:
break
output_logger.error(line)
Problems with this approach:
- You don't have much if any flexibility in directing different parts of TextTestRunner output to different log levels.
- TextTestRunner, if misconfigured, will write a bunch of stuff that you probably don't want. The default verbosity is 1, which will write progress dots while you're testing... which will probably only get in your way in the logging output.
- If you do this naïvely, you'll call
stream_logger.run()
only after you've written all your output to the stream. Thus, you won't get your logging output in real time, and your logging timestamps will be useless. You could solve this by spawning a separate thread for reading, for example, but then you'd need to choose/roll a stream that can handle a reader and writer thread working simultaneously, or fork a process and ditch the in-memory stream, or something relatively complicated.
The approach I'd suggest instead is to forego streams and simply roll your own test runner – called, say, LoggingTestRunner – that writes the test output to the logger in precisely the way you want it output. This will allow you to avoid all three of these problems.
精彩评论