在pytest测试中记录日志

我想在测试函数中放入一些日志语句来检查一些状态变量。

我有以下代码片段:

import pytest,os
import logging


logging.basicConfig(level=logging.DEBUG)
mylogger = logging.getLogger()


#############################################################################


def setup_module(module):
''' Setup for the entire module '''
mylogger.info('Inside Setup')
# Do the actual setup stuff here
pass


def setup_function(func):
''' Setup for test functions '''
if func == test_one:
mylogger.info(' Hurray !!')


def test_one():
''' Test One '''
mylogger.info('Inside Test 1')
#assert 0 == 1
pass


def test_two():
''' Test Two '''
mylogger.info('Inside Test 2')
pass


if __name__ == '__main__':
mylogger.info(' About to start the tests ')
pytest.main(args=[os.path.abspath(__file__)])
mylogger.info(' Done executing the tests ')

我得到以下输出:

[bmaryada-mbp:/Users/bmaryada/dev/platform/main/proto/tests/tpch $]python minitest.py
INFO:root: About to start the tests
======================================================== test session starts =========================================================
platform darwin -- Python 2.6.2 -- pytest-2.0.0
collected 2 items


minitest.py ..


====================================================== 2 passed in 0.01 seconds ======================================================
INFO:root: Done executing the tests

注意,只有来自'__name__ == __main__'块的日志消息被传输到控制台。

是否有一种方法强制pytest从测试方法发出日志到控制台?

176177 次浏览

为我工作,这是我得到的输出:[剪辑->的例子是不正确的]

编辑:似乎你必须将-s选项传递给py。测试,这样它就不会捕获标准输出。在这里(py。测试未安装),使用python pytest.py -s pyt.py就足够了。

对于你的代码,你所需要做的就是将-sargs中传递给main:

 pytest.main(args=['-s', os.path.abspath(__file__)])

看py。捕获输出上的测试文档。

从3.3版开始,pytest支持实时日志记录,这意味着在测试中发出的所有日志记录将立即打印到终端。该特性被记录在生活日志部分。默认情况下禁用实时日志记录;要启用它,在pyproject.toml1pytest.ini2配置中设置log_cli = 1。实时日志记录支持发送到终端和文件;相关选项允许自定义记录:

终端:

  • log_cli_level
  • log_cli_format
  • log_cli_date_format

文件:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

正如这样的评论中的凯文横档所指出的,可以通过以下方式从命令行覆盖ini选项:

< p > -o OVERRIDE_INI, --override-ini=OVERRIDE_INI
用“option=value”覆盖ini选项风格,例如
        __ ABC0 < / p >

因此,与其在pytest.ini中声明log_cli,不如直接调用:

$ pytest -o log_cli=true ...

例子

用于演示的简单测试文件:

# test_spam.py


import logging


LOGGER = logging.getLogger(__name__)




def test_eggs():
LOGGER.info('eggs info')
LOGGER.warning('eggs warning')
LOGGER.error('eggs error')
LOGGER.critical('eggs critical')
assert True

如您所见,不需要额外的配置;pytest将根据pytest.ini中指定的选项或从命令行传递的选项自动设置记录器。

实时日志记录到终端,INFO级别,花式输出

pyproject.toml中的配置:

[tool.pytest.ini_options]
log_cli = true
log_cli_level = "INFO"
log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)"
log_cli_date_format = "%Y-%m-%d %H:%M:%S"

遗留pytest.ini中的相同配置:

[pytest]
log_cli = 1
log_cli_level = INFO
log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format=%Y-%m-%d %H:%M:%S

运行测试:

$ pytest test_spam.py
=============================== test session starts ================================
platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.3, pluggy-0.7.1 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-4673373, inifile: pytest.ini
collected 1 item


test_spam.py::test_eggs
---------------------------------- live log call -----------------------------------
2018-08-01 14:33:20 [    INFO] eggs info (test_spam.py:7)
2018-08-01 14:33:20 [ WARNING] eggs warning (test_spam.py:8)
2018-08-01 14:33:20 [   ERROR] eggs error (test_spam.py:9)
2018-08-01 14:33:20 [CRITICAL] eggs critical (test_spam.py:10)
PASSED                                                                        [100%]


============================= 1 passed in 0.01 seconds =============================

实时日志记录到终端和文件,只有消息&在终端中CRITICAL级别,在pytest.log文件中花哨的输出

pyproject.toml中的配置:

[tool.pytest.ini_options]
log_cli = true
log_cli_level = "CRITICAL"
log_cli_format = "%(message)s"


log_file = "pytest.log"
log_file_level = "DEBUG"
log_file_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)"
log_file_date_format = "%Y-%m-%d %H:%M:%S"

遗留pytest.ini中的相同配置:

[pytest]
log_cli = 1
log_cli_level = CRITICAL
log_cli_format = %(message)s


log_file = pytest.log
log_file_level = DEBUG
log_file_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_file_date_format=%Y-%m-%d %H:%M:%S

测试运行:

$ pytest test_spam.py
=============================== test session starts ================================
platform darwin -- Python 3.6.4, pytest-3.7.0, py-1.5.3, pluggy-0.7.1 -- /Users/hoefling/.virtualenvs/stackoverflow/bin/python3.6
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow/so-4673373, inifile: pytest.ini
collected 1 item


test_spam.py::test_eggs
---------------------------------- live log call -----------------------------------
eggs critical
PASSED                                                                        [100%]


============================= 1 passed in 0.01 seconds =============================


$ cat pytest.log
2018-08-01 14:38:09 [    INFO] eggs info (test_spam.py:7)
2018-08-01 14:38:09 [ WARNING] eggs warning (test_spam.py:8)
2018-08-01 14:38:09 [   ERROR] eggs error (test_spam.py:9)
2018-08-01 14:38:09 [CRITICAL] eggs critical (test_spam.py:10)

1 pyproject.toml自6.0版开始支持,是IMO的最佳选项。详细说明请参见PEP 518

虽然你也可以在[tool:pytest]部分的setup.cfg中配置pytest,但当你想提供自定义的实时日志格式时,不要尝试这样做。其他读取setup.cfg的工具可能会把%(message)s这样的东西当作字符串插值而失败。无论如何,最好的选择是使用pyproject.toml,但如果你被迫使用传统的ini风格格式,请坚持使用pytest.ini以避免错误。

在pytest中使用pytest --log-cli-level=DEBUG可以正常工作(从6.2.2测试到7.1.1)

使用 pytest --log-cli-level=DEBUG --capture=tee-sys也将打印stdtout

使用命令行发送--capture=no标志打开记录器输出。 --capture=no将显示记录器和print语句的所有输出。如果你想捕获记录器的输出,而不是打印语句,请使用--capture=sys

pytest --capture=no tests/system/test_backoffice.py

在这里是关于“捕获标准输出/标准输出”的更多信息;

默认记录器输出级别为"WARNING" 修改日志输出级别使用--log-cli-level标志

pytest --capture=no --log-cli-level=DEBUG tests/system/test_backoffice.py

如果你使用vscode,使用以下配置,假设你已经安装 Python官方插件 (ms-python.python)用于您的Python项目。

./.vscode/setting.json在你的项目

{
....
"python.testing.pytestArgs": ["-s", "src"], //here before discover-path src
"python.testing.unittestEnabled": false,
"python.testing.nosetestsEnabled": false,
"python.testing.pytestEnabled": true,
...
}

附注:一些插件可以在它上工作,包括但不限于:

  • 针对Visual Studio代码的Python测试资源管理器 (littlefoxteam.vscode-python-test-adapter)
  • 测试Visual Studio代码的资源管理器 (hbenl.vscode-test-explorer)

用于登录pytest的文档
下面是一个简单的例子,你可以从foo函数中运行并获取log

#./test_main.py
from main import foo
import logging


def test_foo(caplog):
caplog.set_level(logging.INFO)


logging.getLogger().info('Log inside a test function!')


assert foo(1, 2) == 5
/* your test here*/
# ./main.py
import logging


def foo(a, b):
logging.getLogger().info('a: ' + str(a))
logging.getLogger().info('b: ' + str(b))
return a + b
现在您可以运行pytest并从函数中获得所需的日志信息。
如果没有任何错误,日志将被省略
如果你想用命令行过滤日志,你可以传递——log-cli-level (pytest——log-cli-level) 日志将从您指定的级别及以上显示

(例如pytest——log-cli-level =信息将显示INFO和以上日志(WARNING, ERROR, CRITICAL))

注意:default——log-cli-level如果你没有指定它是一个警告(https://docs.pytest.org/en/6.2.x/logging.html)

但是如果你不想每次使用pytest时都使用——log-cli-level, 你可以设置进行日志级别 在你的pytest配置文件(pytest.ini/tox.ini/setup.cfg)

.cfg

如。

进行日志级别=信息放在pytest.ini(或我提到的其他配置文件)中

当你运行pytest时,你只能看到INFO和以上日志