используйте doctest и вход в программу Python - PullRequest
4 голосов
/ 27 апреля 2010

#!/usr/bin/python2.4
import logging
import sys
import doctest
def foo(x):
        """
    >>> foo (0)
    0
        """
        print ("%d" %(x))
        _logger.debug("%d" %(x))
def _test():
        doctest.testmod()
_logger = logging.getLogger()
_logger.setLevel(logging.DEBUG)
_formatter = logging.Formatter('%(message)s')
_handler = logging.StreamHandler(sys.stdout)
_handler.setFormatter(_formatter)
_logger.addHandler(_handler)
_test()

Я хотел бы использовать модуль логгера для всех моих операторов печати. Я просмотрел первые 50 лучших ссылок Google для этого, и они, похоже, согласны с тем, что doctest использует свою собственную копию стандартного вывода. Если используется print, он работает, если используется logger, он входит в корневую консоль. Может кто-нибудь, пожалуйста, продемонстрируйте рабочий пример с фрагментом кода, который позволит мне объединить. Заметьте, что запуск команды not to test doctest просто добавит вывод журнала в конце теста (при условии, что вы установили переключатели), он не будет обрабатывать их как оператор print.

Ответы [ 3 ]

1 голос
/ 16 сентября 2016

ОК, это простой однострочный текст, который хорошо работает:

В вашем doctest, до того, как потребуется захват журнала, выполните addHandler(logging.Streamhandler(sys.stdout)) на вашем регистраторе. Итак, предположим, logger является вашим объектом регистрации:

"""
This is a doctest that will capture output from the logging module.

>>> logger.addHandler(logging.StreamHandler(sys.stdout))

The rest of your doctest, now able to use output from the logging
module...
"""

Объяснение: После того, как doctest запущен, doctest уже установил свой обман, поэтому sys.stdout теперь имеет значение DocTestRunner._fakeout. Если в этот момент вы создадите logging.StreamHandler для sys.stdout, sys.stdout будет указывать на поддельные документы doctest для sys.stdout, а не на реальный sys.stdout.

Это решение также имеет преимущество, не зависящее от внутренних закрытых переменных в doctest, таких как _fakeout или _SpoofOut, на случай, если они изменятся в будущем.

Если вы получите:

error: [Errno 128] Transport endpoint is not connected

Вы, возможно, забыли import sys.

0 голосов
/ 12 июля 2016

Один простой и универсальный подход выглядит так:

LOGGER = logging.getLogger(__name__)
if hasattr(sys.modules['__main__'], '_SpoofOut'):
    LOGGER.setLevel(logging.DEBUG)
    LOGGER.addHandler(logger.addHandler(logging.StreamHandler()))

Атрибут _SpoofOut вводится модулем doctest. Если он присутствует, вы можете настроить ведение журнала специально для doctest. Например. в моем примере установите подробный режим отладки и войдите в консоль.

0 голосов
/ 28 апреля 2010

Я не уверен, почему вы хотите это сделать, но если вам действительно нужно это сделать, вы можете определить свой собственный подкласс DocTestRunner и переопределить метод run:

#imports left out, code not tested - just to point you in the right direction
class MyDocTestRunner(DocTestRunner):
    def run(self, test, compileflags=None, out=None, clear_globs=True):
        if out is None:
            handler = None
        else:
            handler = StreamHandler(out)
        logger = logging.getLogger() # root logger (say)
        if handler:
            logger.addHandler(handler)
        try:
            DocTestRunner.run(self, test, compileflags, out, clear_globs)
        finally:
            if handler:
                logger.removeHandler(handler)
                handler.close()

Тогда используйте этот бегун вместо DocTestRunner.

...