在 pytest 测试中记录日志

2024-04-09

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

我有以下代码片段:

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也从测试方法将日志记录发送到控制台?


Since version 3.3, pytest supports live logging, meaning that all the log records emitted in tests will be printed to the terminal immediately. The feature is documented under Live Logs https://docs.pytest.org/en/latest/how-to/logging.html#live-logs section. Live logging is disabled by default; to enable it, set log_cli = 1 in the pyproject.toml1 or pytest.ini2 config. Live logging supports emitting to terminal and file; the relevant options allow records customizing:

终端:

  • log_cli_level
  • log_cli_format
  • log_cli_date_format

file:

  • log_file
  • log_file_level
  • log_file_format
  • log_file_date_format

正如所指出的凯文·巴雷 https://stackoverflow.com/users/7505103/k%c3%a9vin-barr%c3%a9 in 这条评论 https://stackoverflow.com/questions/4673373/logging-within-py-test-tests/51633600?noredirect=1#comment91175953_51633600, 压倒一切ini命令行选项可以通过以下方式完成:

-o OVERRIDE_INI, --override-ini=OVERRIDE_INI
使用“option=value”样式覆盖 ini 选项,例如
-o xfail_strict=True -o cache_dir=cache

所以而不是声明log_cli in pytest.ini,您可以简单地调用:

$ pytest -o log_cli=true ...

Examples

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

# 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 file

配置在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 supported since version 6.0 and is the best option IMO. See PEP 518 https://www.python.org/dev/peps/pep-0517/ for the specs.

2 Although you can also configure pytest in setup.cfg under the [tool:pytest] section, don't be tempted to do that when you want to provide custom live logging format. Other tools reading setup.cfg might treat stuff like %(message)s as string interpolation and fail. The best choice is using pyproject.toml anyway, but if you are forced to use the legacy ini-style format, stick to pytest.ini to avoid errors.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 pytest 测试中记录日志 的相关文章

随机推荐

  • Go 运行时错误:“分配给 nil 映射中的条目”

    我是 go lang 的新手 我正在尝试读取 csv 文件并收集数据 但运行后我得到了这个错误 panic assignment to entry in nil map goroutine 1 running panic 0x4dedc0
  • 登录 DBCP

    我正在使用 Apache Commons DBCP 有一个任务来跟踪 DBCP 的内部行为 活动和空闲连接的数量 我发现 DBCP 根本没有任何此类日志记录 是的 当从池中借用连接时 可以编写输出 BasicDataSource 状态的代码
  • 替换 JQueryUI 对话框的关闭图标

    经过对这个主题的广泛搜索后 我无法找到答案 所以希望有人可以帮助我解决这个问题 我有一个相对基本的对话框 dialog search dialog resizable false height dimensionData height wi
  • 使用掺杂向量访问多维数组的任意轴向切片?

    我正在构建一套功能来与多维数组数据结构 https stackoverflow com questions 30023867 how can i work with dynamically allocated arbitrary dimen
  • “enum class”是 C++ 中的类类型吗?

    我读到了 C 中的枚举声明 使用参考参数 http en cppreference com w cpp language enum 然后我做了枚举类并使用检查它是否是类类型std is class include
  • 有没有更简单的方法来访问 R 中类的属性,我可以使用点表示法吗?

    我在 R 中创建了一个包含多个属性的对象 我怎样才能轻松访问它们 我可以 attr x attributeName or attributes x attributeName 但它们都不是真正方便的 有没有更快的方法 如 C 或 Java
  • 无法让属性字符串在 Swift 中工作

    我试图在代码中设置字符串的一些属性 但无法得到NSAttributedString上班 这是应该更改字符串的函数 func getAttributedString string String gt NSAttributedString va
  • 实体框架代码首先迁移抛出错误

    这是我在收到此错误之前所做的操作 安装了 EF 预发布版本 可能是 6 我不知道 决定我不想要 所以卸载它并重新安装稳定版本 5 通过 SSMS 截断我的数据库 这是错误 Exception calling CreateInstanceFr
  • 使用 Spring MVC 应用程序实现 Tiles 3

    我正在尝试在 Spring MVC 应用程序中实现 Apache Tiles 3 因此我在 pom xml 文件中添加了以下依赖项
  • 对多索引 pandas 数据帧上的重复行求和

    你好 我在处理熊猫方面遇到了麻烦 我正在尝试对多索引数据帧上的重复行进行求和 我尝试过df groupby level 0 1 sum 还与df stack reset index groupby year product sum 和其他一
  • Typeorm .loadRelationCountAndMap 返回零

    请帮忙 我正在尝试执行以下 typeorm 查询 return await getRepository Company createQueryBuilder Company leftJoinAndSelect Company plants
  • 在另一个绘图的绘图区域内添加小直方图

    有没有办法在另一个图的绘图区域内添加直方图 但独立于 基础 图的坐标系 就我而言 我想将直方图作为图例添加到分区统计图 直方图将显示属于每个类别的区域数量 但问题可以轻松应用于任何绘图 例如 plot 1 10 rect 1 7 4 9 c
  • pandas DataFrame 中每一行的操作

    我想迭代 pandas DataFrame 中的每一行 并对每行中的元素执行一些操作 现在我有 for row in df iterrows if row col gt 1 5 doSomething 但它告诉我 元组索引必须是整数 而不是
  • 从 C# 打开 Google Chrome 的新窗口

    可以开新的instance来自 C 的 Chrome By instance我的意思是一个新的单独选项卡 不包含在现有的 Chrome 窗口中 我尝试过以下解决方案但是both他们创造了一个new tab in an existingchr
  • MongoDB - 返回插入项的 id

    从以下教程开始 https codeforgeek com 2015 08 restful api node mongodb https codeforgeek com 2015 08 restful api node mongodb 我有
  • MinGW GCC 通配符

    我在 Windows 上使用 MinGW GCC 编译器如何编译目录中的所有 C 文件 I used gcc c o Output 在我输入所需的文件夹后出现此错误 gcc error c Invalid argument gcc fata
  • 在 Julia 中迭代具有不同数量参数的不同函数

    我正在尝试使用不同数量的参数对不同的函数运行循环 变量是在运行时在循环内创建的 我想在每次迭代时使用 eval 来使用变量 symbol 实例化一个 Struct 但是 我不能这样做 因为 eval 只在全局范围内有效 这是有效案例的 MW
  • 当我尝试创建新模型时,Django 错误:名称“_”未定义

    我定义了这个模型 from django db import models from django db models import CharField Create your models here class City models M
  • 从函数中的局部变量返回指针

    我正在读一本叫做 Go 编程语言 的书 在关于指针的第二章中写了以下内容 函数返回局部变量的地址是完全安全的 例如 在 在下面的代码中 由对 f 的特定调用创建的局部变量 v 即使是仍然存在 调用返回后 指针 p 仍将引用它 var p f
  • 在 pytest 测试中记录日志

    我想在测试函数中放置一些日志语句来检查一些状态变量 我有以下代码片段 import pytest os import logging logging basicConfig level logging DEBUG mylogger logg