【问题标题】:python run function in external module containing doctest.testmod()python 在包含 doctest.testmod() 的外部模块中运行函数
【发布时间】:2025-12-16 15:20:05
【问题描述】:

我正在尝试跨多个模块进行自动化测试。所有这些模块都有一个带有单元测试的“test()”函数。一些模块是基本的,它们的测试包含简单的语句,但大多数模块都有 unittest 或 doctest。我在动态导入和运行 doctest 时遇到了最大的麻烦。

例如这里是一个模块sample.py

class sample:
    """
    >>> import sample
    >>> print sample.hello()
    Hello
    """
    def hello():
        return "Hello"

def test():
    import doctest
    doctest.testmod(name=__name__, verbose=True)

这是我的文件run_all_tests.py

# assume I already have a list of all my files to test
for file in all_my_files:
    temp_module = __import__(file)
    temp_module.test()

这不起作用,我总是收到此错误:

1 items had no tests:
    sample
0 tests in 1 items.
0 passed and 0 failed.
Test passed.

请帮我理解问题。

鼻子会是一个不错的选择吗?我不想使用它,因为我事先不知道模块是否使用 doctests、unittests 或简单语句。但是,如果这不是真的,请告诉我/您完全有另一种选择!

【问题讨论】:

    标签: python unit-testing import automated-tests doctest


    【解决方案1】:

    使用doctest.DocTestSuite。它需要一个模块,提取那里存在的所有doctests,并将其作为unittest.TestSuite 返回。然后,运行测试是小菜一碟。您的代码如下所示:

    for f in all_my_files:
        temp_module = __import__(f)
        test_suite = doctest.DocTestSuite(temp_module)
        unittest.TextTestRunner().run(test_suite)
    

    为什么您的代码不起作用

    来自doctest的testmoddocumentation

    在可访问的函数和类中的文档字符串中测试示例 模块 m (或模块 __main__ 如果 m 未提供或为无), 以m.__doc__开头。

    因此,由于您遗漏了第一个参数 (m),因此模块 __main__ 被传递给 testmod。所以运行的文档测试是模块中包含for 循环的文档测试。你可以自己看看:

    run_tests.py

    """
        >>> print 'oops'
        oops
    """
    # assume I already have a list of all my files to test
    for file in all_my_files:
        temp_module = __import__(file)
        temp_module.test()
    

    如果你现在运行你的例子(在修复它之前)你会看到你会得到:

    Trying:
        print 'oops'
    Expecting:
        oops
    ok
    1 items passed all tests:
       1 tests in sample
    1 tests in 1 items.
    1 passed and 0 failed.
    Test passed.
    

    清楚地表明正在运行的 doctest 是 run_tests.py 中的那些。 name 参数仅更改消息中显示的名称 (sample)。

    【讨论】:

    • 是的,我也发现了这一点,我很感激您的回复。你知道为什么简单地调用 temp_module.test() 不起作用吗?
    • 嗯 - 我尝试将 __name__ 作为参数传递给 testmod(),但这根本不起作用。我会进一步研究 - 感谢您的更新!