如何使用 Pytest 防止记录到文件并捕获断言的日志
How to prevent logging to file and capture logs for assertions using Pytest
我有一套 python 模块的单元测试,并使用 Pytest 运行 这些测试。我现在开始在我的库中使用标准日志记录库,需要帮助解决两个问题:
- 如何在 运行 测试套件 时防止记录到文件中,以防止文件增长并防止在实际日志文件中出现无用的条目。
- 如何在单元测试中捕获日志,以便能够 运行 对库生成的日志进行断言。
我正在尝试测试的模块将 __init__.py
中的日志记录库配置为登录文件并使用 info 方法在模块代码中记录条目。这工作正常,当我 运行 代码时,正确的日志条目出现在文件中。 -- 见下面的代码 --
我尝试在 pytest 中使用 caplog
fixture -- 请参阅下面的代码和输出 -- 但我得到的效果是:
- 日志条目包含在文件中(使用 caplog 和所有其他测试在 运行 秒内生成的日志)
caplog.text
为空
单元测试代码
import library.module
class TestFunction:
def test_something_else(self):
library.module.function():
assert True
def test_logs(self,caplog)
library.module.function():
assert "desired" in caplog.text
测试输出
(...)
> assert "desired" in caplog.text
E AssertionError: assert 'desired' in ''
E + where '' = <_pytest.logging.LogCaptureFixture object at (...).text
(...)
运行测试套件
后的日志条目
2021-12-07 11:10:05,915 - library.module - INFO - desired
2021-12-07 11:10:05,917 - library.module - INFO - desired
记录模块配置
__init__.py
import logging.config
import yaml
with open("logging.yaml") as f:
conf_dict = yaml.safe_load(f)
logging.config.dictConfig(conf_dict)
logging.yaml
version: 1
formatters:
simple:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
training:
class: logging.FileHandler
level: DEBUG
formatter: simple
filename: logs/test_log
loggers:
library.module:
level: DEBUG
handlers: [training]
propagate: no
root:
level: DEBUG
handlers: []
待测模块
import logging
logger = logging.getLogger(__name__)
def function():
logger.info("desired")
文件结构
.
├── library
│ ├── module.py
│ └── __init__.py
├── tests
│ └── test_module.py
└── logs
└── test_log
为了避免写入日志文件,我建议,在 test_module.py
中,您只需模拟记录器并在测试中使用它,如下所示:
import pytest
import library.module
@pytest.fixture
def logger(mocker):
return mocker.patch("library.module.logger.info")
class TestFunction:
def test_something_else(self):
library.module.function():
assert True
def test_logs(self,logger)
library.module.function():
logger.assert_called_with("desired")
我有一套 python 模块的单元测试,并使用 Pytest 运行 这些测试。我现在开始在我的库中使用标准日志记录库,需要帮助解决两个问题:
- 如何在 运行 测试套件 时防止记录到文件中,以防止文件增长并防止在实际日志文件中出现无用的条目。
- 如何在单元测试中捕获日志,以便能够 运行 对库生成的日志进行断言。
我正在尝试测试的模块将 __init__.py
中的日志记录库配置为登录文件并使用 info 方法在模块代码中记录条目。这工作正常,当我 运行 代码时,正确的日志条目出现在文件中。 -- 见下面的代码 --
我尝试在 pytest 中使用 caplog
fixture -- 请参阅下面的代码和输出 -- 但我得到的效果是:
- 日志条目包含在文件中(使用 caplog 和所有其他测试在 运行 秒内生成的日志)
caplog.text
为空
单元测试代码
import library.module
class TestFunction:
def test_something_else(self):
library.module.function():
assert True
def test_logs(self,caplog)
library.module.function():
assert "desired" in caplog.text
测试输出
(...)
> assert "desired" in caplog.text
E AssertionError: assert 'desired' in ''
E + where '' = <_pytest.logging.LogCaptureFixture object at (...).text
(...)
运行测试套件
后的日志条目2021-12-07 11:10:05,915 - library.module - INFO - desired
2021-12-07 11:10:05,917 - library.module - INFO - desired
记录模块配置
__init__.py
import logging.config
import yaml
with open("logging.yaml") as f:
conf_dict = yaml.safe_load(f)
logging.config.dictConfig(conf_dict)
logging.yaml
version: 1
formatters:
simple:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
training:
class: logging.FileHandler
level: DEBUG
formatter: simple
filename: logs/test_log
loggers:
library.module:
level: DEBUG
handlers: [training]
propagate: no
root:
level: DEBUG
handlers: []
待测模块
import logging
logger = logging.getLogger(__name__)
def function():
logger.info("desired")
文件结构
.
├── library
│ ├── module.py
│ └── __init__.py
├── tests
│ └── test_module.py
└── logs
└── test_log
为了避免写入日志文件,我建议,在 test_module.py
中,您只需模拟记录器并在测试中使用它,如下所示:
import pytest
import library.module
@pytest.fixture
def logger(mocker):
return mocker.patch("library.module.logger.info")
class TestFunction:
def test_something_else(self):
library.module.function():
assert True
def test_logs(self,logger)
library.module.function():
logger.assert_called_with("desired")