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.
The unit test framework in Python is called unittest , which comes packaged with Python. Unit testing makes your code future proof since you anticipate the cases where your code could potentially fail or produce a bug. Though you cannot predict all of the cases, you still address most of them.
Internally, unittest. main() is using a few tricks to figure out the name of the module (source file) that contains the call to main() . It then imports this modules, examines it, gets a list of all classes and functions which could be tests (according the configuration) and then creates a test case for each of them.
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 thing io.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 wrapping StringIO
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With