пространство имен по умолчанию для python doctest

#python #nose #doctest

#python #nose #doctest

Вопрос:

В тестах моего модуля я хотел бы ссылаться на свой модуль с полным пространством имен, например:

   hp.myfunc(1)
  

И я хотел бы избежать загромождения doctests, написав:

   import healpy as hp
  

в каждом из доктестов.

если я запускаю doctest.testmod, я знаю, что могу использовать globs ключевое слово для предоставления этого, а если я запускаю nose, я могу использовать setup функцию.

Есть ли другой стандартный способ, который мог бы работать с обоими?

Ответ №1:

Как вы запускаете doctests (то есть без nose)? Если вы попали в каталог пакетов при попытке их запуска, вы столкнетесь с проблемами (то есть, если вы выполняете полный импорт).

Мне удалось запустить простой doctest (с полным импортом), работающий как с nosetests, так и со встроенным исполнителем doctest. Вот моя настройка:

Структура проекта:

 .
└── mypackage
    ├── __init__.py
    └── mod.py
  

Вот содержимое моего ‘mod.py » досье:

 """foo() providing module

Example:
    >>> import mypackage.mod
    >>> mypackage.mod.foo()
    'bar'
"""

def foo():
    return "bar"
  

из каталога ‘.’ (корень проекта) теперь я могу запускать тесты:

 $ python -m doctest -v mypackage/*.py
1 items had no tests:
    __init__
0 tests in 1 items.
0 passed and 0 failed.
Test passed.
Trying:
    import mypackage.mod
Expecting nothing
ok
Trying:
    mypackage.mod.foo()
Expecting:
    'bar'
ok
1 items had no tests:
    mod.foo
1 items passed all tests:
   2 tests in mod
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
  

И теперь nosetests:

 $ nosetests --with-doctest
.
----------------------------------------------------------------------
Ran 1 test in 0.008s

OK
  

Если я попытаюсь запустить doctest из каталога ‘mypackage’, я получаю сообщение об ошибке (что, я подозреваю, происходит в вашем случае).

Наконец, я не думаю, что это должно иметь значение, но я использую Python 2.7.2

Комментарии:

1. спасибо за ваш ответ, я бы хотел избежать написания «import mypackage.mod» в начале каждого doctest. Поэтому я ищу стандартный способ автоматического его импорта вместо использования глобусов или специфичной для nose функции настройки.

2. Похоже, что ответ на мой вопрос заключается в том, что не существует стандартного способа изменить пространство имен всех doctests, которое работало бы с разными исполнителями тестов. Таким образом, единственный способ — написать add import перед каждым doctest. Итак, я принял и присудил этот ответ.

3. @Andrea, спасибо … жаль слышать, что вы не нашли лучшего ответа. Вероятно, лучшим решением для этого, кроме «это невозможно сделать», было бы написать плагин для nose для заполнения глобусов при запуске doc-тестов… Не уверен, что в этом были задействованы усилия.

4. нет, целью было бы иметь что-то стандартное. С плагином для nose мне пришлось бы отправить плагин.

Ответ №2:

Я не знаю о nose, но вы можете использовать globs аргумент в testmod() и testfile() .

Вот простой модуль (называемый foobar.py ), обратите внимание, что я не импортирую os :

 #!/usr/bin/python
"""
    >>> os.pipe
    <built-in function pipe>
"""
  

Вы можете протестировать модуль следующим образом (пример консоли):

 $ python2.7
Python 2.7.2 (default, Jun 29 2011, 11:10:00) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import doctest, foobar
2
>>> doctest.testmod(foobar)  ## will fail as expected because os has not been imported
**********************************************************************
File "foobar.py", line 2, in foobar
Failed example:
    os.pipe
Exception raised:
    Traceback (most recent call last):
      File "/usr/lib/python2.7/doctest.py", line 1254, in __run
        compileflags, 1) in test.globs
      File "<doctest foobar[0]>", line 1, in <module>
        os.pipe
    NameError: name 'os' is not defined
**********************************************************************
1 items had failures:
   1 of   1 in foobar
***Test Failed*** 1 failures.
TestResults(failed=1, attempted=1)
>>> import os
>>> globs = {'os': os}
>>> doctest.testmod(foobar, globs=globs)
TestResults(failed=0, attempted=1)
>>> # Win :)
  

В вашем примере должно быть сказано:

 globs = {'hp': healp}
  

Комментарии:

1. спасибо, но, как я уже писал в своем вопросе, я уже знаю, что могу использовать globs, и я не хочу указывать его каждый раз, когда хочу запускать тесты, а также, с nose это не сработает.