如何在Python中将logging模块与unittest模块结合使用?
我想用Python的日志模块来记录unittest的所有输出,这样我就可以把它整合进我正在写的测试框架里。我的目标是运行测试时能有两种输出,一种是简单的输出,告诉我测试步骤是什么,另一种是更详细的调试输出,这样当出现问题时,我们能获取尽可能多的信息。这些输出会被放到两个文件里,一个是我可以发给别人的,另一个是留着以防失败。我注意到TextTestRunner可以使用一个流,这个流能和日志模块一起用吗?我打算使用一些Python 2.7的新特性。
1 个回答
1
你可以这样做,但我不确定这是不是最好的方法。
如果你选择这种方法,你需要:
创建一个内存中的流,这样就可以被
TextTestRunner
使用。这里io.StringIO
是个不错的选择,但它只支持 Unicode 输入,而且我不确定TextTestRunner
是否能正确地将 Unicode 写入这个流。你也可以自己写一个内存流,来满足你的需求,可能需要用一个编码器来包装StringIO
。创建你自己的
TextTestRunner
,并用这个内存流来初始化它。创建一个类,从流中读取内容并将其写入日志。
这可以简单到:
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)
这种方法的问题:
- 你在将
TextTestRunner
的不同输出部分导向不同日志级别时,几乎没有灵活性。 - 如果
TextTestRunner
配置错误,它会写出很多你可能不想要的内容。默认的详细程度是 1,这会在测试时输出进度点……这可能会干扰你的日志输出。 - 如果你简单粗暴地这样做,你会在写完所有输出到流后才调用
stream_logger.run()
。这样,你就无法实时获取日志输出,日志的时间戳也没用。你可以通过启动一个单独的线程来读取来解决这个问题,但那样你需要选择一个可以同时处理读写线程的流,或者分叉一个进程,放弃内存流,这些都比较复杂。
我建议的做法是放弃流,直接创建一个自己的测试运行器——比如叫它 LoggingTestRunner
——这样就可以按照你想要的方式将测试输出写入日志。这将帮助你避免上述三个问题。