我想为每个测试方法创建一个单独的日志文件。我想在 conftest.py 文件中执行此操作,并将日志文件实例传递给测试方法。这样,每当我在测试方法中记录某些内容时,它都会记录到单独的日志文件中,并且非常容易分析。
我尝试了以下方法。在 conftest.py 文件中我添加了以下内容:
logs_dir = pkg_resources.resource_filename("test_results", "logs")
def pytest_runtest_setup(item):
    test_method_name = item.name
    testpath = item.parent.name.strip('.py')
    path = '%s/%s' % (logs_dir, testpath)
    if not os.path.exists(path):
        os.makedirs(path)
    log = logger.make_logger(test_method_name, path) # Make logger takes care of creating the logfile and returns the python logging object.
这里的问题是 pytest_runtest_setup 无法向测试方法返回任何内容。至少,我不知道。
因此,我想到在 conftest.py 文件中创建一个带有scope =“function”的固定方法,并从测试方法中调用此固定装置。但是,fixture 方法不知道 Pytest.Item 对象。对于 pytest_runtest_setup 方法,它接收 item 参数,并使用该参数我们能够找到测试方法名称和测试方法路径。
请帮忙!
我通过进一步研究webh的答案找到了这个解决方案。我尝试使用pytest-logger但它们的文件结构非常严格,对我来说并不是很有用。我发现这段代码无需任何插件即可工作。它基于set_log_path,这是一个实验性功能。
Pytest 6.1.1 和 Python 3.8.4
# conftest.py
# Required modules
import pytest
from pathlib import Path
# Configure logging
@pytest.hookimpl(hookwrapper=True,tryfirst=True)
def pytest_runtest_setup(item):
    config=item.config
    logging_plugin=config.pluginmanager.get_plugin("logging-plugin")
    filename=Path('pytest-logs', item._request.node.name+".log")
    logging_plugin.set_log_path(str(filename))
    yield
Path请注意,可以用 代替 的使用os.path.join。此外,可以在不同的文件夹中设置不同的测试,并通过在文件名上使用时间戳来记录历史上完成的所有测试。例如,可以使用以下文件名:
# conftest.py
# Required modules
import pytest
import datetime
from pathlib import Path
# Configure logging
@pytest.hookimpl(hookwrapper=True,tryfirst=True)
def pytest_runtest_setup(item):
   ...
   filename=Path(
      'pytest-logs',
       item._request.node.name,
       f"{datetime.datetime.now().strftime('%Y%m%dT%H%M%S')}.log"
       )
   ...
此外,如果想要修改日志格式,可以按照文档pytest中的描述在配置文件中进行更改。
# pytest.ini
[pytest]
log_file_level = INFO
log_file_format = %(name)s [%(levelname)s]: %(message)
我的第一个 stackoverflow 答案!