Тестирование Python для сценариев оболочки, которые проверяют синтаксический анализ аргументов без загрязнения строки документации с помощью os.popen () - PullRequest
7 голосов
/ 02 апреля 2012

Есть ли способ написать строку doctest для python для тестирования скрипта, предназначенного для запуска из командной строки (терминала), который не загрязняет примеры документации при помощи вызовов os.popen?

#!/usr/bin/env python
# filename: add
"""
Example:
>>> import os
>>> os.popen('add -n 1 2').read().strip()
'3'
"""

if __name__ == '__main__':
    from argparse import ArgumentParser
    p = ArgumentParser(description=__doc__.strip())
    p.add_argument('-n',type = int, nargs   = 2, default = 0,help  = 'Numbers to add.')
    p.add_argument('--test',action = 'store_true',help  = 'Test script.')
    a = p.parse_args()
    if a.test:
        import doctest
        doctest.testmod()
    if a.n and len(a.n)==2:
        print a.n[0]+a.n[1]

Запуск doctest.testmod () без использования popen просто вызывает сбой теста, поскольку скрипт запускается в оболочке python вместо оболочки bash (или DOS).

Продвинутый курс Python LLNL предлагает помещать скрипты в файлы, которые отделены от модулей .py. Но тогда строки doctest только проверяют модуль, без разбора аргумента. И мой подход os.popen () загрязняет документацию примеров. Есть ли лучший способ?

Ответы [ 2 ]

4 голосов
/ 12 июля 2012

Только что нашел что-то похожее на нужный вам ответ: shell-doctest .

1 голос
/ 02 апреля 2012

doctest предназначен для запуска кода на Python, поэтому вам нужно где-то выполнить преобразование.Если вы намерены протестировать интерфейс командной строки напрямую через doctest, одна из возможностей состоит в том, чтобы выполнить подстановку регулярного выражения в __doc__, прежде чем передать его в argparse, чтобы извлечь оболочку os.popen:

clean = re.sub(r"^>>> os\.popen\('(.*)'\).*", r"% \1", __doc__)
p = ArgumentParser(description=clean, ...)

(Конечно, есть разные способы сделать это лучше, в зависимости от того, что вы считаете "хорошим").

Это очистит его для конечного пользователя.Если вы также хотите, чтобы в исходном коде он выглядел чище, вы можете пойти другим путем: поместите примеры командной строки в строку документации и не используйте doctest.testmodule ().Запустите вашу строку документации через doctest.script_from_examples и постобработайте ее, чтобы вставить вызовы os.(Затем вам нужно будет встроить его во что-то, чтобы вы могли проверить его с помощью run_docstring_examples.) doctest не имеет значения, является ли ввод допустимым Python, поэтому вы можете сделать следующее:

>>> print doctest.script_from_examples("""
Here is a commandline example I want converted:
>>> add -n 3 4
7
""")
# Here is a commandline example I want converted:
add -n 3 4
# Expected:
## 7

Это по-прежнему будет отображать приглашение Python >>> в справке.Если это вас беспокоит, возможно, вам придется обработать строку в обоих направлениях.

...