2015-04-17 6 views
1

Гипотетически говоря, моя функция возвращает значение и имеет множество заявлений на печать (может быть, 100 или более).Есть ли способ выполнять только доктрины, игнорируя вызовы функций печати?

Есть ли способ запустить doctest таким образом, что вся другие печати работа может быть проигнорирована/пропущено (я знаком с +SKIP директивы, которая предназначена для пропуска doctest примеров), то есть, когда я выполняю свою функцию (или запустить мой модуль как скрипт) с doctest с:

python mymodule.py 

Или:

python -m doctest mymodule.py 

я должен получить:

  • ничего, в случае успеха; или
  • сообщения об ошибках в случае сбоя любого тестового примера;

и ничего больше. Запуск doctest не должен давать мне окно терминала с выводами/текстом из этих print вызовов функций.

Пожалуйста, не предлагайте использовать модульное тестирование (например, unittest), поскольку оно убьет суть вопроса.

ответ

3

doctest использует stdout, неstderr, чтобы показать сообщения от любых непройденных тестов. Поэтому вы не можете исправить stdout, поскольку этот ответ изначально был предложен - это подавит ваши print звонки и любые сообщения от doctest.


Одним из вариантов является определение функций, print с дополнительным verbose параметром, так что вы можете подавить это, когда это необходимо.

def foo(verbose=True): 
    """Does whatever. 

     >>> foo(verbose=False) 

    """ 
    if verbose: 
     print('Hello world') 

Хотя вам необходимо изменить функции, это также дает вам полезные опции, если не тестируется.


Другое явно поставить соответствующую print функции с функциями, которые используют его, что позволяет передавать NOOP во время выполнения:

def bar(print=print): 
    """Does whatever. 

     >>> bar(print=lambda *args, **kwargs: None) 

    """ 
    print('Hello world') 

Это также требует изменений функционирования определений, но, по крайней мере, избегает изменений в корпусах этих функций.


Третий вариант залатать из print для всего модуля испытуемой, например:

def baz(): 
    """Does whatever. 

     >>> baz() 

    """ 
    print('Hello world') 

if __name__ == '__main__': 

    import doctest 

    print = lambda *args, **kwargs: None 

    doctest.testmod() 

Обратите внимание, что это влияет на результаты, которые doctest видит, тоже, так что вы не включают любой из результатов print в докштрике (я предполагаю, что это хорошая новость!) Однако он не будет работать с python -m doctest mymodule.py.

+0

очень хорошо. для этого последнего случая, как насчет 'COMMAND = os.path.splitext (os.path.basename (sys.argv [0])) [0]; print = (lambda * args, ** kwargs: None), если COMMAND == 'doctest' else print' ...? –

+0

@jcomeau_ictx Я бы защитил переназначение, а не использовал тернарное выражение, но это сработает, если вам понадобится этот край. – jonrsharpe

+0

Да, я бы тоже, если бы не пытался ввести его в поле комментариев: smile: –

1

в дополнение к отличному ответу jonrsharpe, есть еще один способ, что делает работает с конструкцией python3 -m doctest module.py.

#!/usr/bin/python3 -OO 
''' 
Some ideas for adding additional verbosity during doctest, and for 
reducing verbosity and startup delays during doctest or pydoc. 
''' 
from __future__ import print_function # for compatibility with python2 
import sys, os, logging 
logging.basicConfig(level = logging.DEBUG if __debug__ else logging.INFO) 
COMMAND = os.path.splitext(os.path.basename(sys.argv[0]))[0] 
if COMMAND in ['doctest', 'pydoc']: 
    NONDOCTESTPRINT = lambda *args, **kwargs: None 
    DOCTESTDEBUG = logging.debug 
else: 
    NONDOCTESTPRINT = print 
    DOCTESTDEBUG = lambda *args, **kwargs: None 
    # You can also use this `else` block to import things not needed during 
    # doctest, especially slow-loading modules like `requests`, 
    # or to do some other verbose or slow initialization. 

def test(string): 
    ''' 
    print string after lead-in 

    >>> test("I'm in love with you!") 
    Listen! 
    I'm in love with you! 
    ''' 
    DOCTESTDEBUG("If this works, you shouldn't see anything but this") 
    print('Listen!') 
    NONDOCTESTPRINT('Do you want to know a secret?') 
    NONDOCTESTPRINT('Do you promise not to tell? Whoa, oh...') 
    NONDOCTESTPRINT('Closer...') 
    NONDOCTESTPRINT('Let me whisper in your ear...') 
    NONDOCTESTPRINT('Say the words you long to hear...') 
    print(string) 

if __name__ == '__main__': 
    test(' '.join(sys.argv[1:]) or 'Taxation is theft.') 

Вот как выглядит результат, в зависимости от того, как он называется.

[email protected]:/tmp$ python3 -m doctest doctesttest.py 
DEBUG:root:If this works, you shouldn't see anything but this 
[email protected]:/tmp$ python3 doctesttest.py This is a test! 
Listen! 
Do you want to know a secret? 
Do you promise not to tell? Whoa, oh... 
Closer... 
Let me whisper in your ear... 
Say the words you long to hear... 
This is a test! 

и pydoc doctesttest:

pydoc output of above script

+1

«Налогообложение - это кража». это политика, должны быть поп-песни или ссылки Монти Питона. Так как вы искали, чтобы их обнаружили. –

Смежные вопросы