使用 python3 且不带 __init__.py 文件的递归单元测试发现



我有以下目录结构的项目:

.
├── requirements.txt
├── main.py
├── tests
    ├── unit
    │   └── test_thing1.py
    │   └── test_thing2.py
    └── integration
        └── test_integration_thing1.py
        └── test_integration_thing2.py

我想用一个命令运行所有测试。如果我这样做python -m unittest discover,则不会执行任何测试。

我发现这个问题建议添加一个__init__.py文件以从unitintegration文件夹中制作包。该解决方案有效,并且所有测试都以这种方式运行。

但是由于我使用的是 python3 并且隐式命名空间包不需要__init__.py文件,我想知道是否有办法在没有这些__init__.py文件的情况下使其工作。

我研究了一下,认为它很可能是一个错误。

所以我创建了一个python错误报告和一个PR来为我解决问题。

克隆它,

看看它是否也适合您,通过修复运行发现的最佳方法是python -m unittest discover -s tests。否则,它将查找例如低于顶部目录的虚拟环境。

请注意,命名空间包是常规包。您一定不能期望命名空间包被视为与常规包相同。

也请阅读这篇文章。https://dev.to/methane/don-t-omit-init-py-3hga

我看不出在每个子目录中强制创建__init__.py的意义,至少在我的情况下是这样:我正在测试C++代码的 Python 包装器,所以我没有测试我已经实现的 Python 模块。此外,我还存在忘记创建一些__init__.py文件的风险,这会导致静默跳过测试。

因此,这里有一个不必在每个子目录中创建__init__.py的解决方案:

import glob
import os
import unittest
def test_suite_from_recursive_discover(pattern):
    test_files = glob.glob('**/{}'.format(pattern), recursive=True)
    test_dirs = list(set(([os.path.dirname(os.path.abspath(test_file)) for test_file in test_files])))
    suites = [unittest.TestLoader().discover(start_dir=d, pattern=pattern) for d in test_dirs]
    suite = unittest.TestSuite(suites)
    return suite
if __name__ == "__main__":
    unittest.TextTestRunner().run(test_suite_from_recursive_discover('test*.py'))

使用 pytest。它确实会发现文件夹中的测试。

在您的情况下,您只需要通过 pip ( pip install pytest ) 安装,然后在您的根文件夹 pytest tests 中运行。

最新更新