我通常会在模块中编写单元测试和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()
运行套件中的其他案例?或者我只是困惑和迷惑?
再一次,我会感激任何人都可以提供帮助。
答案 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。
答案 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
例如。