python 运行 包含 doctest.testmod() 的外部模块中的函数

python run function in external module containing doctest.testmod()

我正在尝试跨多个模块进行自动化测试。所有这些模块的单元测试都有一个 "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.

请帮助我理解问题。

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

使用doctest.DocTestSuite. It takes a module, extracts all doctests that exist there, and returns it as a unittest.TestSuite。然后,运行测试是小菜一碟。您的代码将如下所示:

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

为什么您的代码无法正常工作

来自 doctest 的 testmod documentation

Test examples in docstrings in functions and classes reachable from module m (or module __main__ if m is not supplied or is None), starting with m.__doc__.

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

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.

清楚地表明 doctests 运行ning 是 run_tests.py 中的那些。 name 参数仅更改出现在消息中的名称 (sample)。