使用单元测试中的doctests

时间:2011-04-15 19:19:48

标签: python

我通常会在模块中编写单元测试和doctests。我想在运行测试套件时自动运行我的所有doctests。我认为这是可能的,但我的语法很难。

我有测试套件

import unittest
class ts(unittest.TestCase):
    def test_null(self): self.assertTrue(True)
if __name__ == '__main__': unittest.main()

我想在此套件中添加模块module1中的所有doctests。我怎样才能做到这一点?我已经阅读了python docs,但我在这里并没有接近成功。添加行

import doctest
import module1
suite = doctest.DocTestSuite(module1)

不起作用。 unittest.main()搜索当前文件范围并运行它找到的每个测试 case ,对吗?但DocTestSuite会生成测试套件。如何让unittest.main()运行套件中的其他案例?或者我只是困惑和迷惑?

再一次,我会感激任何人都可以提供帮助。

5 个答案:

答案 0 :(得分:12)

对这个老问题的更新:自Python版本2.7起,就有load_tests protocol,不再需要编写自定义代码。它允许您添加一个函数load_tests(),测试加载器将执行该函数以更新其当前模块的单元测试集合。

在您的代码模块中放置这样的函数,将模块自己的doctests打包到unittest的测试套件中:

def load_tests(loader, tests, ignore):
    tests.addTests(doctest.DocTestSuite())
    return tests

或者,将这样的函数放入单元测试模块,将另一个模块(例如package.code_module)的doctests添加到已经存在的测试套件中:

def load_tests(loader, tests, ignore):
    tests.addTests(doctest.DocTestSuite(package.code_module))
    return tests

使用unittest.TestLoader方法loadTestsFromModule()loadTestsFromName()discover()时,unittest使用包含单元测试和doctests的测试套件。

答案 1 :(得分:8)

在此代码中,我组合了来自导入模块的单元测试和doctests

import unittest


class ts(unittest.TestCase):
    def test_null(self):
        self.assertTrue(True)


class ts1(unittest.TestCase):
    def test_null(self):
        self.assertTrue(True)

testSuite = unittest.TestSuite()    
testSuite.addTests(unittest.makeSuite(ts))
testSuite.addTest(unittest.makeSuite(ts1))

import doctest
import my_module_with_doctests

testSuite.addTest(doctest.DocTestSuite(my_module_with_doctests))
unittest.TextTestRunner(verbosity = 2).run(testSuite)

答案 2 :(得分:2)

我建议在没有任何load_test协议的情况下使用pytest --doctest-modules。你可以简单地将带有普通pytests的文件或目录以及带有doctests的模块添加到pytest调用中。

  

pytest --doctest-modules path / to / pytest / unittests path / to / modules

它也发现并运行所有doctests。

请参阅https://docs.pytest.org/en/latest/doctest.html

答案 3 :(得分:1)

此代码将自动运行包中所有模块的doctests,而无需为每个模块手动添加测试套件。这可以与Tox一起使用。

import doctest
import glob
import os
import sys
if sys.version_info < (2,7,):
    import unittest2 as unittest
else:
    import unittest

import mypackage as source_package

def load_module_by_path(path):
    """Load a python module from its path.

    Parameters
    ----------
    path : str
        Path to the module source file.

    Returns
    -------
    mod : module
        Loaded module.
    """
    import imp

    module_file_basename = os.path.basename(path)
    module_name, ext = os.path.splitext(module_file_basename)
    mod = imp.load_source(module_name, path)
    return mod

def file_contains_doctests(path):
    """Scan a python source file to determine if it contains any doctest examples.

    Parameters
    ----------
    path : str
        Path to the module source file.

    Returns
    -------
    flag : bool
        True if the module source code contains doctest examples.
    """
    with open(path) as f:
        for line in f:
            if ">>>" in line:
                return True
    return False

def load_tests(loader, tests, pattern):
    """Run doctests for all modules"""
    source_dir = os.path.dirname(source_package.__path__[0])
    python_source_glob = os.path.join(source_dir, source_package.__name__, "*.py")
    python_source_files = glob.glob(python_source_glob)
    for python_source_file in python_source_files:
        if not file_contains_doctests(python_source_file):
            continue
        module = load_module_by_path(python_source_file)
        tests.addTests(doctest.DocTestSuite(module))
    return tests

答案 4 :(得分:-1)

zope.testing模块提供了这样的功能。

http://www.veit-schiele.de/dienstleistungen/schulungen/testen/doctests

例如。