Как управлять лесозаготовками¶
pytest автоматически перехватывает сообщения журнала уровня WARNING
или выше и отображает их в отдельном разделе для каждого неудачного теста так же, как перехваченные stdout и stderr.
Запуск без вариантов:
pytest
Показывает неудачные тесты следующим образом:
----------------------- Captured stdlog call ----------------------
test_reporting.py 26 WARNING text going to logger
----------------------- Captured stdout call ----------------------
text going to stdout
----------------------- Captured stderr call ----------------------
text going to stderr
==================== 2 failed in 0.02 seconds =====================
По умолчанию каждое перехваченное сообщение журнала показывает модуль, номер строки, уровень журнала и сообщение.
При желании формат журнала и даты может быть задан любой, который поддерживает модуль протоколирования, путем передачи определенных параметров форматирования:
pytest --log-format="%(asctime)s %(levelname)s %(message)s" \
--log-date-format="%Y-%m-%d %H:%M:%S"
Показывает неудачные тесты следующим образом:
----------------------- Captured stdlog call ----------------------
2010-04-10 14:48:44 WARNING text going to logger
----------------------- Captured stdout call ----------------------
text going to stdout
----------------------- Captured stderr call ----------------------
text going to stderr
==================== 2 failed in 0.02 seconds =====================
Эти параметры также могут быть настроены через файл pytest.ini
:
[pytest]
log_format = %(asctime)s %(levelname)s %(message)s
log_date_format = %Y-%m-%d %H:%M:%S
Далее можно полностью отключить отчет о перехваченном содержимом (stdout, stderr и журналы) при неудачных тестах:
pytest --show-capture=no
крепление капсюля¶
Внутри тестов можно изменить уровень журнала для перехваченных сообщений журнала. Это поддерживается приспособлением caplog
:
def test_foo(caplog):
caplog.set_level(logging.INFO)
По умолчанию уровень устанавливается для корневого регистратора, однако для удобства можно установить уровень журнала для любого регистратора:
def test_foo(caplog):
caplog.set_level(logging.CRITICAL, logger="root.baz")
Установленные уровни журнала восстанавливаются автоматически по окончании теста.
Также можно использовать менеджер контекста для временного изменения уровня журнала внутри блока with
:
def test_bar(caplog):
with caplog.at_level(logging.INFO):
pass
Опять же, по умолчанию затрагивается уровень корневого регистратора, но уровень любого регистратора может быть изменен с помощью:
def test_bar(caplog):
with caplog.at_level(logging.CRITICAL, logger="root.baz"):
pass
Наконец, все журналы, отправленные в регистратор во время выполнения теста, становятся доступными на приспособлении в виде экземпляров logging.LogRecord
и окончательного текста журнала. Это полезно, когда вы хотите проверить содержимое сообщения:
def test_baz(caplog):
func_under_test()
for record in caplog.records:
assert record.levelname != "CRITICAL"
assert "wally" not in caplog.text
Все доступные атрибуты записей журнала см. в классе logging.LogRecord
.
Вы также можете прибегнуть к record_tuples
, если все, что вы хотите сделать, это убедиться, что определенные сообщения были зарегистрированы под заданным именем регистратора с заданной серьезностью и сообщением:
def test_foo(caplog):
logging.getLogger().info("boo %s", "arg")
assert caplog.record_tuples == [("root", logging.INFO, "boo arg")]
Вы можете вызвать caplog.clear()
для сброса захваченных записей журнала в тесте:
def test_something_with_clearing_records(caplog):
some_method_that_creates_log_records()
caplog.clear()
your_test_method()
assert ["Foo"] == [rec.message for rec in caplog.records]
Атрибут caplog.records
содержит записи только текущего этапа, поэтому внутри этапа setup
он содержит только журналы установки, то же самое с этапами call
и teardown
.
Чтобы получить доступ к журналам других этапов, используйте метод caplog.get_records(when)
. Например, если вы хотите убедиться, что тесты, использующие определенное приспособление, никогда не выдают предупреждений, вы можете просмотреть записи для этапов setup
и call
во время разрушения следующим образом:
@pytest.fixture
def window(caplog):
window = create_window()
yield window
for when in ("setup", "call"):
messages = [
x.message for x in caplog.get_records(when) if x.levelno == logging.WARNING
]
if messages:
pytest.fail(f"warning messages encountered during testing: {messages}")
Полная версия API доступна по адресу pytest.LogCaptureFixture
.
Живые журналы¶
Установив параметр конфигурации log_cli
в значение true
, pytest будет выводить записи протоколирования по мере их появления непосредственно в консоль.
Вы можете указать уровень протоколирования, для которого записи журнала с равным или более высоким уровнем будут выводиться на консоль, передав --log-cli-level
. Этот параметр принимает имена уровней протоколирования или числовые значения, как показано в logging’s documentation.
Кроме того, вы можете указать --log-cli-format
и --log-cli-date-format
, которые зеркально отражают и по умолчанию соответствуют --log-format
и --log-date-format
, если не указаны, но применяются только к обработчику логирования консоли.
Все опции журнала CLI также можно задать в конфигурационном INI-файле. Имена опций следующие:
log_cli_level
log_cli_format
log_cli_date_format
Если вам нужно записать в файл журнал вызовов всего набора тестов, вы можете передать --log-file=/path/to/log/file
. Этот файл журнала открывается в режиме записи, что означает, что он будет перезаписываться при каждом сеансе запуска тестов. Обратите внимание, что относительные пути для расположения лог-файла, переданные в CLI или объявленные в конфигурационном файле, всегда определяются относительно текущего рабочего каталога.
Вы также можете указать уровень протоколирования для файла журнала, передав параметр --log-file-level
. Этот параметр принимает имена уровней протоколирования или числовые значения, как показано в logging’s documentation.
Дополнительно можно указать --log-file-format
и --log-file-date-format
, которые равны --log-format
и --log-date-format
, но применяются к обработчику логирования файла журнала.
Все параметры файла журнала можно также установить в конфигурационном INI-файле. Имена опций следующие:
log_file
log_file_level
log_file_format
log_file_date_format
Вы можете вызвать set_log_path()
для динамической настройки пути к log_file. Эта функциональность считается экспериментальной.
Настройка цветов¶
Уровни журнала окрашиваются, если включен цветной вывод терминала. Изменение цветов по умолчанию или наложение цвета на пользовательские уровни журнала поддерживается через add_color_level()
. Пример:
@pytest.hookimpl
def pytest_configure(config):
logging_plugin = config.pluginmanager.get_plugin("logging-plugin")
# Change color on existing log level
logging_plugin.log_cli_handler.formatter.add_color_level(logging.INFO, "cyan")
# Add color to a custom log level (a custom log level `SPAM` is already set up)
logging_plugin.log_cli_handler.formatter.add_color_level(logging.SPAM, "blue")
Предупреждение
Эта функция и ее API считаются экспериментальными и могут изменяться между выпусками без уведомления об обесценивании.
Примечания к выпуску¶
Эта функция была введена в качестве замены плагина pytest-catchlog, и они конфликтуют друг с другом. API обратной совместимости с pytest-capturelog
был отменен, когда была введена эта функция, поэтому если по этой причине вам все еще нужен pytest-catchlog
, вы можете отключить внутреннюю функцию, добавив ее в pytest.ini
:
[pytest]
addopts=-p no:logging
Несовместимые изменения в pytest 3.4¶
Эта функция была представлена в 3.3
, и некоторые несовместимые изменения были внесены в 3.4
после отзывов сообщества:
Уровни журналов больше не изменяются, если они явно не запрошены конфигурацией
log_level
или опциями командной строки--log-level
. Это позволяет пользователям самим настраивать объекты логгеров. Настройкаlog_level
устанавливает уровень, который фиксируется глобально, поэтому если для конкретного теста требуется более низкий уровень, чем этот, используйте функциональностьcaplog.set_level()
, иначе тест будет склонен к сбоям.Live Logs теперь отключен по умолчанию и может быть включен установкой параметра конфигурации
log_cli
в значениеtrue
. При включении этого параметра увеличивается точность, так что протоколирование каждого теста становится видимым.Live Logs теперь отправляются в
sys.stdout
и больше не требуют опции командной строки-s
для работы.
Если вы хотите частично восстановить поведение протоколирования версии 3.3
, вы можете добавить эту опцию в ваш файл ini
:
[pytest]
log_cli=true
log_level=NOTSET
Более подробно об обсуждении, которое привело к этим изменениям, можно прочитать в issue #3013.