Может ли python doctest игнорировать некоторые выходные строки? - PullRequest
26 голосов
/ 21 июня 2009

Я бы хотел написать такой тест:

"""
>>> print a.string()
          foo : a
          bar : b
         date : <I don't care about the date output>
          baz : c
"""

Есть ли способ сделать это? Я думаю, что было бы более разумно перейти на unittest, но мне любопытно, можно ли указать диапазон выходных данных, который не должен совпадать для теста в doctest.

Спасибо!

Ответы [ 6 ]

37 голосов
/ 21 июня 2009

С doctest.ELLIPSIS вы можете использовать ... для обозначения «соответствовать любой строке здесь». Вы можете установить параметры doctest с помощью директивы doctest, чтобы сделать ее активной только для одного тестового случая: один пример в онлайн-документах :

>>> print range(20) # doctest:+ELLIPSIS
[0, 1, ..., 18, 19]

Если вы хотите, чтобы параметр doctest был активным, вы можете передать его в качестве аргумента optionflags= любым функциям doctest, которые вы используете, например, doctest.testfile. (Вы можете передать несколько флагов опций там, используя оператор | для бит или их).

12 голосов
/ 22 февраля 2012

Отвечая на вопросы о том, «как мы можем игнорировать всю строку»: да, тот факт, что «...» также выглядит как продолжение, затрудняет игнорирование всего вывода. Вы можете использовать "#doctest: + SKIP", если вы просто хотите полностью пропустить пример, но это не сработает, если вы полагаетесь на его побочные эффекты. Если вам действительно нужно сделать это, я полагаю, вы могли бы обезопасить сам модуль doctest, хотя я бы не рекомендовал его:

>>> import doctest
>>> doctest.ELLIPSIS_MARKER = '-etc-'
>>> print 12 # doctest: +ELLIPSIS
-etc-

(этот тест проходит.)

Или вы можете временно отключить stdout и / или stderr:

>>> # Suppress stdout
>>> import sys
>>> class DevNull:
...     def noop(*args, **kwargs): pass
...     close = write = flush = writelines = noop
>>> sys.stdout = DevNull()
>>> # Run a test and ignore output (but we need its side effects)
>>> print 12 # NOTE: stdout is suppressed!
>>> # Restore stdout
>>> sys.stdout = sys.__stdout__

(этот тест также проходит.)

7 голосов
/ 22 февраля 2012

Игнорирование всей строки немного сложно. Здесь:

"""
>>> do_your_thing() #doctest:+ELLIPSIS
...
"""

Тройная точка будет интерпретирована как продолжение строки и приведет к синтаксической ошибке.

Если вы хотите игнорировать всю строку, вам понадобится что-то вроде:

"""
>>> sys.stdout.write('skip from here '); do_your_thing() #doctest:+ELLIPSIS
skip from here ...
"""
5 голосов
/ 20 марта 2014

Мне было проще просто присвоить ненужные возвращаемые значения переменной:

>>> _ = do_something()
>>> check_something()
True
4 голосов
/ 28 октября 2015

Вы можете написать кортежи до и после своей функции (взлом, вдохновленный ответом Марка Хорват):

def foo():
    """
    >>> ();foo();() # doctest: +ELLIPSIS
    (...)
    """
    print "Hello world"
    return "Hello world"
0 голосов
/ 01 сентября 2012

Могу ли я иметь многоточие в начале строки в тесте Python? объясняет, как создать настраиваемую проверку выходных данных, которая использует дополнительную строку в качестве многоточия. Это позволит вам написать следующее, в то же время все еще используя «...».

def foo():
  """
  >>> foo() # doctest: +ELLIPSIS
  [...] world
  """
  print "hello world"
...