【问题标题】:pdb is not working in django doctestspdb 在 django doctests 中不起作用
【发布时间】:2010-05-21 14:22:24
【问题描述】:

所以我创建了以下文件 (testlib.py) 来自动将所有 doctests(在我的嵌套项目目录中)加载到 __tests__ 的 test.py 字典中:

# ./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())

所有这些都可以很好地从我的所有文件和子目录中加载我的文档测试。 问题是当我在任何地方导入和调用pdb.set_trace()时,我看到的只有这些:

(Pdb) l
(Pdb) args
(Pdb) n
(Pdb) n
(Pdb) l
(Pdb) cont

doctest 显然是在捕获和调解输出本身,并在评估测试时使用输出。因此,当测试运行完成时,当我在 doctest 的失败报告中的 pdb shell 中时,我会看到 应该 打印出的所有内容。无论我是在 doctest 行内还是在被测试的函数或方法内调用 pdb.set_trace(),都会发生这种情况。

显然,这是一个很大的拖累。 Doctest 很棒,但如果没有交互式 pdb,我无法调试它们检测到的任何故障以修复它们。

我的思考过程是可能将 pdb 的输出流重定向到绕过 doctest 捕获输出的东西,但我需要一些帮助来确定执行此操作所需的低级 io 内容。另外,我什至不知道这是否可能,而且我对 doctest 的内部结构太不熟悉了,不知道从哪里开始。有没有人有任何建议,或者更好的代码可以完成这项工作?

【问题讨论】:

    标签: python django pdb doctest


    【解决方案1】:

    我可以通过调整它来获得 pdb。我只是将以下代码放在我的 testlib.py 文件的底部:

    import sys, pdb
    class TestPdb(pdb.Pdb):
        def __init__(self, *args, **kwargs):
            self.__stdout_old = sys.stdout
            sys.stdout = sys.__stdout__
            pdb.Pdb.__init__(self, *args, **kwargs)
    
        def cmdloop(self, *args, **kwargs):
            sys.stdout = sys.__stdout__
            retval = pdb.Pdb.cmdloop(self, *args, **kwargs)
            sys.stdout = self.__stdout_old
    
    def pdb_trace():
        debugger = TestPdb()
        debugger.set_trace(sys._getframe().f_back)
    

    为了使用调试器,我只需 import testlib 并调用 testlib.pdb_trace() 并进入一个功能齐全的调试器。

    【讨论】:

      猜你喜欢
      • 2023-01-13
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 2015-09-15
      • 2012-02-21
      • 2012-04-04
      • 2013-07-28
      • 1970-01-01
      相关资源
      最近更新 更多