从Python 2.7开始,testing发现在unittest包中自动完成。 从文档 :

Unittest支持简单的testing发现。 为了与testing发现兼容,所有testing文件都必须是可从项目的顶级目录导入的模块或包(这意味着它们的文件名必须是有效的标识符)。

testing发现在TestLoader.discover() ,但也可以从命令行使用。 基本的命令行用法是:

cd project_directory python -m unittest discover

默认情况下,它会查找名为test*.py软件包,但是这个可以改变,所以你可以使用类似的东西

python -m unittest discover --pattern=*.py

代替你的test.py脚本。

这是我的testing发现代码,似乎做的工作。 我想确保我可以轻松地扩展testing,而不必在任何相关文件中列出testing,但也要避免将所有testing写入单个“最佳”文件。

所以结构是

myTests.py testDir\ __init__.py testA.py testB.py

myTest.py看起来像这样:

import unittest if __name__ == '__main__': testsuite = unittest.TestLoader().discover('.') unittest.TextTestRunner(verbosity=1).run(testsuite)

我相信这是在一个目录中编写几个testing用例最简单的解决scheme。 该解决scheme需要Python 2.7或Python 3。

我知道有一个明显的解决办法:

dirFoo\ __init__.py test.py dirBar\ Foo.py Bar.py

dirFoo / test.py的内容

from dirBar import * import unittest if __name__ == "__main__": unittest.main()

运行testing:

$ python test.py ........... ---------------------------------------------------------------------- Ran 11 tests in 2.305s OK

对不起,这个愚蠢的问题。

你应该尝试鼻子 。 这是一个图书馆,帮助创buildtesting,它与unit testing或doctest集成。 所有你需要做的就是运行nosetests ,它会find你所有的单位testing。

% nosetests # finds all tests in all subdirectories % nosetests tests/ # find all tests in the tests directory

我想出了一个可以做你想做的事情的片段。 它沿着你提供的寻找Python包/模块的path,并从这些模块中累积一组testing套件,然后一次执行它们。

关于这一点的好处是,它可以在所有指定目录下嵌套的软件包上工作,而且您不必在添加新组件时手动更改导入。

import logging import os import unittest MODULE_EXTENSIONS = set('.py .pyc .pyo'.split()) def unit_test_extractor(tup, path, filenames): """Pull ``unittest.TestSuite``s from modules in path if the path represents a valid Python package. Accumulate results in `tup[1]`. """ package_path, suites = tup logging.debug('Path: %s', path) logging.debug('Filenames: %s', filenames) relpath = os.path.relpath(path, package_path) relpath_pieces = relpath.split(os.sep) if relpath_pieces[0] == '.': # Base directory. relpath_pieces.pop(0) # Otherwise, screws up module name. elif not any(os.path.exists(os.path.join(path, '__init__' + ext)) for ext in MODULE_EXTENSIONS): return # Not a package directory and not the base directory, reject. logging.info('Base: %s', '.'.join(relpath_pieces)) for filename in filenames: base, ext = os.path.splitext(filename) if ext not in MODULE_EXTENSIONS: # Not a Python module. continue logging.info('Module: %s', base) module_name = '.'.join(relpath_pieces + [base]) logging.info('Importing from %s', module_name) module = __import__(module_name) module_suites = unittest.defaultTestLoader.loadTestsFromModule(module) logging.info('Got suites: %s', module_suites) suites += module_suites def get_test_suites(path): """:return: Iterable of suites for the packages/modules present under :param:`path`. """ logging.info('Base path: %s', package_path) suites = [] os.path.walk(package_path, unit_test_extractor, (package_path, suites)) logging.info('Got suites: %s', suites) return suites if __name__ == '__main__': logging.basicConfig(level=logging.WARN) package_path = os.path.dirname(os.path.abspath(__file__)) suites = get_test_suites(package_path) for suite in suites: unittest.TextTestRunner(verbosity=2).run(suite)

如果它碰巧帮助任何人,这是我解决这个问题的方法。 我有用例,我有以下的目录结构:

mypackage/ tests/ test_category_1/ tests_1a.py tests_1b.py ... test_category_2/ tests_2a.py tests_2b.py ... ...

我希望以下所有内容都能够以明显的方式工作,并且能够提供与unittest所接受的相同的命令行参数:

python -m mypackage.tests python -m mypackage.tests.test_category_1 python -m mypackage.tests.test_category_1.tests_1a

解决方法是像这样设置mypackage/tests/__init__.py :

import unittest def prepare_load_tests_function (the__path__): test_suite = unittest.TestLoader().discover(the__path__[0]) def load_tests (_a, _b, _c): return test_suite return load_tests

并像这样设置mypackage/tests/__main__.py :

import unittest from . import prepare_load_tests_function, __path__ load_tests = prepare_load_tests_function(__path__) unittest.main()

并在每个mypackage/tests/test_category_n/复制并粘贴一个空的__init__.py和下面的__main__.py :

import unittest from .. import prepare_load_tests_function from . import __path__ load_tests = prepare_load_tests_function(__path__) unittest.main()

并在每个实际testing文件中添加标准if __name__ == '__main__': unittest.main() 。

(适用于Windows上的Python 3.3,ymmv。)