Таким образом, я создал следующий файл (testlib.py), чтобы автоматически загрузить все doctests (на протяжении всех моих вложенных каталогов проекта) в __tests__
словаря tests.py:PDB не работает в Джанго doctests
# ./testlib.py
import os, imp, re, inspect
from django.contrib.admin import site
def get_module_list(start):
all_files = os.walk(start)
file_list = [(i[0], (i[1], i[2])) for i in all_files]
file_dict = dict(file_list)
curr = start
modules = []
pathlist = []
pathstack = [[start]]
while pathstack is not None:
current_level = pathstack[len(pathstack)-1]
if len(current_level) == 0:
pathstack.pop()
if len(pathlist) == 0:
break
pathlist.pop()
continue
pathlist.append(current_level.pop())
curr = os.sep.join(pathlist)
local_files = []
for f in file_dict[curr][1]:
if f.endswith(".py") and os.path.basename(f) not in ('tests.py', 'models.py'):
local_file = re.sub('\.py$', '', f)
local_files.append(local_file)
for f in local_files:
# This is necessary because some of the imports are repopulating the registry, causing errors to be raised
site._registry.clear()
module = imp.load_module(f, *imp.find_module(f, [curr]))
modules.append(module)
pathstack.append([sub_dir for sub_dir in file_dict[curr][0] if sub_dir[0] != '.'])
return modules
def get_doc_objs(module):
ret_val = []
for obj_name in dir(module):
obj = getattr(module, obj_name)
if callable(obj):
ret_val.append(obj_name)
if inspect.isclass(obj):
ret_val.append(obj_name)
return ret_val
def has_doctest(docstring):
return ">>>" in docstring
def get_test_dict(package, locals):
test_dict = {}
for module in get_module_list(os.path.dirname(package.__file__)):
for method in get_doc_objs(module):
docstring = str(getattr(module, method).__doc__)
if has_doctest(docstring):
print "Found doctests(s) " + module.__name__ + '.' + method
# import the method itself, so doctest can find it
_temp = __import__(module.__name__, globals(), locals, [method])
locals[method] = getattr(_temp, method)
# Django looks in __test__ for doctests to run. Some extra information is
# added to the dictionary key, because otherwise the info would be hidden.
test_dict[method + "@" + module.__file__] = getattr(module, method)
return test_dict
Для дать кредит, где кредит должен, многое из этого вышел из here
В моем файле tests.py, у меня есть следующий код:
# ./project/tests.py
import testlib, project
__test__ = testlib.get_test_dict(project, locals())
Все Тзи s работает достаточно хорошо, чтобы загрузить мои досье из всех моих файлов и подкаталогов. проблема в том, что когда я импортировать и вызывать pdb.set_trace() везде, это все, что я вижу:
(Pdb) l
(Pdb) args
(Pdb) n
(Pdb) n
(Pdb) l
(Pdb) cont
doctest по-видимому, захватывая и посредническую сам вывод, и использует вывод в оценке тесты. Итак, когда тестовый запуск завершается, я вижу все, что должно было напечатано, когда я был в оболочке pdb в отчете об отказе от отчета. Это происходит независимо от того, вызываю ли я pdb.set_trace() внутри строки doctest или внутри тестируемой функции или метода.
Очевидно, что это большое сопротивление. Doctests великолепны, но без интерактивного pdb я не могу отлаживать какие-либо ошибки, которые они обнаруживают, чтобы исправить их.
Мой мыслительный процесс - это, возможно, перенаправление выходного потока pdb на то, что обходит захват doctest выходным сигналом, но мне нужна помощь в выяснении низкоуровневого материала io, который потребуется для этого. Кроме того, я даже не знаю, возможно ли это, и я слишком незнакома с внутренними структурами, чтобы знать, с чего начать. У кого-нибудь есть какие-то предложения или, лучше, какой-то код, который может это сделать?
Спасибо, что помогли мне – Goin