Как я могу объединить ведение журнала stdlib с py.test

Я использую py.test для тестирования некоторых моих модулей, которые содержат довольно много журналов stdlib. Я, конечно, хотел бы, чтобы ведение журнала выводилось на стандартный вывод, который фиксируется py.test, чтобы я получал все соответствующие сообщения журнала, если тест не пройден.

Проблема заключается в том, что модуль ведения журнала в конечном итоге пытается записать сообщения в объект 'stdout', предоставленный py.test после того, как этот объект был отброшен py.test. То есть я получаю:

Traceback (most recent call last):
  File "/usr/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/usr/lib/python2.6/logging/__init__.py", line 1508, in shutdown
    h.flush()
  File "/usr/lib/python2.6/logging/__init__.py", line 754, in flush
    self.stream.flush()
ValueError: I/O operation on closed file

Если я отключу захват с помощью -s, у меня не возникнет никаких проблем, но, конечно, это сделает вывод теста нечитаемым из-за ненужной регистрации.

Может ли кто-нибудь сказать мне, как правильно интегрировать ведение журнала stdlib с py.test?

(Я попытался просмотреть это, где, похоже, он должен работать без проблем, так что мне не помогло)


person porgarmingduod    schedule 18.01.2011    source источник
comment
не могли бы вы показать нам, как вы запускаете свой код py.test? Если это произойдет, это должно быть так, что ведение журнала настроено и инициализировано ДО py.test, но этого не должно происходить, если вы запускаете код через исполняемый файл py.test.   -  person Alan Franzoni    schedule 22.01.2011
comment
Я запускаю его, используя базовую командную строку py.test, и позволяю ему собирать и запускать все, что ему заблагорассудится.   -  person porgarmingduod    schedule 22.01.2011


Ответы (3)


Регистрация/захват взаимодействий должна лучше работать с предстоящим выпуском 2.0.1, который вы уже можете установить в виде моментального снимка разработки:

pip install -i http://pypi.testrun.org pytest 

Вы должны получить как минимум «2.0.1.dev9», когда впоследствии наберете «py.test --version». И проблема/ошибка, которую вы опубликовали, теперь должна исчезнуть.

Немного предыстории: пакет протоколирования настаивает на «владении» потоками, которые он использует, и по умолчанию он захватывает sys.stderr и настаивает на его закрытии при выходе из процесса, зарегистрированном через модуль atexit. py.test заменяет sys.stdout временным файлом для вывода моментального снимка (включая вывод на уровне дескриптора файла, чтобы также перехватывать вывод подпроцесса). Таким образом, py.test эволюционировал, чтобы быть очень осторожным, чтобы всегда использовать один и тот же временный файл, чтобы не жаловаться на atexit-код ведения журнала.

Не то чтобы вы также могли установить плагин [pytest-capturelog][1], который поможет еще немного справиться с выводом журнала.

[1] http://pypi.python.org/pypi/pytest-capturelog/0.7< /а>

person hpk42    schedule 22.01.2011

Если вы не возражаете против ведения журнала в никуда после того, как объекты были отброшены py.test, вы можете установить переменную уровня модуля logging.raiseExceptions в False где-то в начале ваших модулей или тестов.

Это заставит модуль ведения журнала проглатывать исключения, возникающие в подсистеме ведения журнала. (Также хорошая практика для производственных систем, где вы не хотите, чтобы ошибки в журнале приводили к сбою вашей системы)

Вы также можете использовать logging.basicConfig() для установки вывода журнала в отдельный файл. Но это, вероятно, не то, что вы хотите.

person Hanno S.    schedule 21.01.2011

Все, что вам нужно сделать, это передать параметр -s в py.test, чтобы он не перехватывал стандартный вывод.

person rubik    schedule 18.01.2011
comment
Если я отключу захват с помощью -s, у меня не будет никаких проблем, но, конечно, это сделает вывод теста нечитаемым из-за ненужного ведения журнала. - person porgarmingduod; 18.01.2011