在py.test测试中记录

sup*_*tor 66 python logging 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 ')
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

[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 
Run Code Online (Sandbox Code Playgroud)

请注意,只有来自'__name__ == __main__'块的日志消息才会传输到控制台.

有没有办法强制pytest从测试方法发出日志记录到控制台?

hoe*_*ing 64

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

终奌站:

  • log_cli_level
  • log_cli_format
  • log_cli_date_format

文件:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

注意:log_cliflag不能从命令行传递,必须pytest.ini(或-o/--override)中设置.所有其他选项既可以从命令行传递,也可以在配置文件中设置.正如KévinBarré本评论中指出的那样,可以通过log_cli选项覆盖命令行中的ini 选项.因此,您可以简单地调用:而不是pytest.inipytest/ 中声明pytest.ini:

$ pytest -o log_cli=true ...
Run Code Online (Sandbox Code Playgroud)

例子

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

# 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
Run Code Online (Sandbox Code Playgroud)

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

实时记录到终端,CRITICAL级别,花式输出

配置在pytest.log:

[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
Run Code Online (Sandbox Code Playgroud)

运行测试:

$ 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 =============================
Run Code Online (Sandbox Code Playgroud)

实时记录到终端和文件,只有终端中的消息和pytest.ini级别,pytest文件中的花式输出

配置在setup.cfg:

[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
Run Code Online (Sandbox Code Playgroud)

测试运行:

$ 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)
Run Code Online (Sandbox Code Playgroud)

  • 关于“ log_cli”必须在_pytest.ini_中的注释,看来您可以使用-o选项覆盖命令行中的值。pytest -o log_cli = true --log-cli-level = DEBUG对我有用。 (6认同)
  • @OfekAgmon如果你想存储`pytest`输出,你可以使用`--result-log`参数(尽管注意它已被弃用,[这里是替代方案](https://docs.pytest.org/en/最新/deprecations.html#result-log-result-log))。但是,您不能将“pytest”输出和实时日志输出存储在同一个文件中。 (2认同)
  • @andrea 是的,您可以通过编程方式更改选项;我无法在评论中发布片段,因此请查看我对类似问题的回答([链接](/sf/answers/4240038631/))。调整的选项是`log_file`而不是`htmlpath`;如果您对此有任何困难,请写一个新问题并再次在这里联系我,我将添加一个工作示例。 (2认同)

Try*_*yPy 26

对我有用,这是我得到的输出:[snip - >示例不正确]

编辑:似乎你必须将-s选项传递给py.test,因此它不会捕获标准输出.这里(py.test没有安装),它足以使用 python pytest.py -s pyt.py.

对于你的代码,你需要的是通过-sargsmain:

 pytest.main(args=['-s', os.path.abspath(__file__)])
Run Code Online (Sandbox Code Playgroud)

有关捕获输出的信息,请参阅py.test文档.


fja*_*mes 15

使用pytest --log-cli-level=DEBUGpytest-6.2.2 工作正常


Vla*_*den 6

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

pytest --capture=no tests/system/test_backoffice.py
Run Code Online (Sandbox Code Playgroud)

是有关“捕获标准输出/标准输出”的更多信息

默认情况下,记录器输出级别为“警告”要更改日志输出级别使用--log-cli-level标志。

pytest --capture=no --log-cli-level=DEBUG tests/system/test_backoffice.py
Run Code Online (Sandbox Code Playgroud)


小智 5

如果你想用命令行过滤日志,你可以通过--log-cli-level (pytest --log-cli-level) ,日志将从你指定的级别及以上显示

(例如pytest --log-cli-level=INFO将显示 INFO 及以上日志(警告、错误、严重))

请注意:如果您未指定默认 --log-cli-level ,则它是一个警告(https://docs.pytest.org/en/6.2.x/logging.html

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

例如

log-level=INFO放入 pytest.ini (或我提到的其他配置文件)

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