#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 это не сработает.