【发布时间】:2021-05-21 23:53:19
【问题描述】:
编辑:感谢@eemz 提出重新设计结构并使用from unittest.mock import patch 的想法,但问题仍然存在。
所以我最近偶然发现了 unittest,我有一个程序,我通常像这样 python run.py -config /path/to/config.file -y 开始。我想在单独的test.py 文件中编写一个简单的测试:执行脚本,传递提到的参数并获取其所有输出。我传递了一个缺少某些东西的准备好的配置文件,因此run.py 将中断并使用logging.error 准确记录此错误:“xyz 在配置文件中丢失!” (见下面的例子)。我会从print() 那里得到几句话,然后logging 实例会启动并从那里开始处理。我如何获得它的输出以便我可以检查它?请随意重写,因为我还在学习中,请多多包涵。
简化示例:
run.py
import logging
def run(args):
< args.config = /path/to/config.file >
cnfg = Config(args.config)
cnfg.logger.info("Let's start with the rest of the code!") # This is NOT in 'output' of the unittest
< code >
if __name__ == "__main__":
print("Welcome! Starting execution.") # This is in 'output' of the unittest
< code to parse arguments 'args' >
run(args)
Config.py
import logging
class Config:
def __init__(self):
print("Creating logging instance, hold on ...") # This is in 'output' of the unittest
logger = logging.getLogger(__name__)
console_handler = logging.StreamHandler()
logger.addHandler(console_handler)
logger.info("Logging activated, let's go!") # This is NOT in 'output' of the unittest
self.logger = logger
if xyz not in config:
self.logger.error("xyz was missing in Config file!") # This is NOT in 'output' of the unittest
exit(1)
test.py
import unittest
from unittest.mock import patch
class TestConfigs(unittest.TestCase):
def test_xyz(self):
with patch('sys.stdout', new=StringIO()) as capture:
with self.assertRaises(SystemExit) as cm:
run("/p/to/f/missing/xyz/f", "", False, True)
output = capture.getvalue().strip()
self.assertEqual(cm.exception.code, 1)
# Following is working, because the print messages are in output
self.assertTrue("Welcome! Starting execution." in output)
# Following is NOT working, because the logging messages are not in output
self.assertTrue("xyz was missing in Config file!" in output)
if __name__ == "__main__":
unittest.main()
【问题讨论】:
-
不直接相关,但 pytest 可能值得研究,因为它是 unittest 的超集,并且在错误时提供更好的堆栈跟踪
标签: python unit-testing testing logging python-unittest