Как управлять лесозаготовками¶
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_levellog_cli_formatlog_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_filelog_file_levellog_file_formatlog_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.