惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
博客园_首页
宝玉的分享
宝玉的分享
S
SegmentFault 最新的问题
Jina AI
Jina AI
Hugging Face - Blog
Hugging Face - Blog
V
Visual Studio Blog
美团技术团队
IT之家
IT之家
罗磊的独立博客
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
博客园 - 叶小钗
M
MIT News - Artificial intelligence
B
Blog RSS Feed
有赞技术团队
有赞技术团队
Y
Y Combinator Blog

jdhao's digital space

Conversion between base64 and OpenCV or PIL Image 腾讯云对象存储博客图床开启 CDN 加速(不需要购买额外域名) Search and Replace in Multiple Files in Vim/Neovim Change Table Column Width in LaTeX Image or Table Side by Side in LaTeX LaTeX 并排显示图像或表格 Firenvim: Neovim inside Your Browser Content inside HTML tags missing in Latest Hugo? Creating Markdown Front Matter with Ultisnips Labelme JSON 标注格式转 voc XML 格式 Nifty Nvim Techniques That Make My Life Easier -- Series 6 macOS 下如何为视频制作字幕 Running Command Asynchronously inside Neovim Resolving Merge Conflict after Git Stash Pop Pylint: command not found? A Hands-on Experience with Neovim's Built-in LSP Support How to Convert PDF to Images with Imagemagick 互联网上常用缩略语集锦 File Backup in Neovim Converting PDF Pages to Images with Poppler Nifty Nvim Techniques That Make My Life Easier -- Series 5 Neovim Configuration for System-wide Use How to sort a list of tuple or list in Python -- lambda or itemgetter? Building A Vim Statusline from Scratch 人类第一颗原子弹爆炸始末 Distributed Training in PyTorch with Horovod Learning Expect Programming Essential Knowledge about SSH Nifty LaTeX Techniques -- Series 1 更改 Adsense 邮寄地址,重新寄送 PIN
Logging setup for Pytest
2025-10-30 · via jdhao's digital space

When you do code testing using pytest, pytest can do sophisticated changes to your logging. This is a very powerful feature, but carries some subtlety.

log_cli and log_cli_level#

Suppose that we have the following test case:


import logging
logger = logging.getLogger()

def test_something():
    logger.debug("Debug message")
    logger.info("Info message")
    logger.warning("Warn message")
    logger.error("Error message")

    assert True

[log_cli][pytest-option-log-cli] can control whether to enable live log on cli. Note that this option does not have a command line equivalent (i.e., it can only be set in config file) We can use option log_cli_level (or --log-cli-level on cli) to control the logging printed on command line.

If we have the following pytest config (use pytest.ini):

[pytest]
log_cli = true
log_cli_level = WARN

If you run pytest, you will see that only WARN and Error logging is shown on cli. If you have log_cli_level = INFO, you see INFO, WARN and ERROR logging. So under the hood, it seems log_cli_level will also set your root logger level1.

log_cli_level vs log_level#

There is another option log_level that controls the log level of root logger. Based on experiments, log_level has priority over log_cli_level in setting the root logger. This is easy to verify. We change the test case a bit:

import logging
logger = logging.getLogger()

def test_something():
    foo = 123
    logger.debug("Debug message")
    logger.info("Info message %", foo)
    logger.warning("Warn message")
    logger.error("Error message")

    assert True

The INFO logging is ill-formatted and will error out if it is run. We use the following pytest config:


[pytest]
log_cli = true
log_cli_level = WARN
log_level = INFO

If you run pytest, you will see format errors:

ValueError: incomplete format

You will not see error if you use this config (logging is only initialized starting with WARN level):

[pytest]
log_cli = true
log_cli_level = INFO
log_level = WARN

caplog fixture#

There is another level of complication. If you use caplog.set_level() fixture inside test, it can also change the logging level. Now we change our test case to the following:

import logging
logger = logging.getLogger()

def test_something(caplog):
    caplog.set_level(logging.WARN)

    foo = 123
    logger.debug("Debug message")
    logger.info("Info message %", foo)
    logger.warning("Warn message")
    logger.error("Error message")

    assert True

On the command line, if you run pytest --log-cli-level=INFO, the test is still going to pass: caplog.set_level has silently override the logging level you set via --log-cli-level. The effect of caplog.set_level make is only in this test only.