在 Python 项目中,test 目录(通常命名为 tests)的放置位置主要有两种主流且被广泛接受的做法:
📂 1. 项目根目录下,与主包目录平级 (最推荐)
这是目前 最主流、最推荐 的方式,尤其受到 pytest 等流行测试框架的支持。
- 结构示例:
my_project/ ├── my_package/ # 主项目代码包 │ ├── __init__.py │ ├── module1.py │ └── module2.py ├── tests/ # 测试目录 (推荐使用复数形式 tests) │ ├── __init__.py # (可选,但常见) │ ├── test_module1.py # 测试文件,通常以 test_ 开头 │ └── test_module2.py ├── setup.py # 或 setup.cfg, pyproject.toml ├── requirements.txt └── README.md - 优点:
- 清晰分离: 测试代码与生产代码完全分离,结构一目了然。
- 避免打包: 测试代码通常不需要被打包分发到最终用户环境。放在根目录下可以方便地在
setup.py/pyproject.toml中通过exclude配置排除tests目录。 - 工具友好:
pytest、unittest等工具默认就能发现并运行这个位置的测试,无需额外配置搜索路径。 - 项目标准: 这是许多大型开源项目(如
requests,flask,numpy,pandas)和社区工具(如Cookiecutter模板)采用的结构。
📦 2. 放在每个子包/模块目录内 (较少见)
这种方式将测试文件直接放在它们所测试的代码旁边。
- 结构示例:
my_project/ ├── my_package/ │ ├── __init__.py │ ├── module1.py │ ├── tests/ # 为 module1 的测试 │ │ ├── __init__.py │ │ └── test_module1.py │ └── module2.py ├── setup.py ├── requirements.txt └── README.md - 优点:
- 紧耦合: 测试与其对应的功能代码物理位置非常接近,对于理解特定模块的功能和测试可能更直观。
- 缺点:
- 污染包结构: 将测试代码混入生产代码包中,可能导致包结构混乱。
- 打包隐患: 如果不仔细配置打包工具(
setup.py/pyproject.toml),测试代码可能会被意外包含在分发包中。 - 运行复杂: 需要更仔细地配置测试运行器来收集所有分散的测试,或者在每个子目录单独运行测试。
- 不常用: 在现代 Python 项目中远不如第一种方式普及。
📌 强烈建议与最佳实践
- 首选
tests在根目录: 对于绝大多数项目,将tests目录(使用复数形式)放在项目根目录下,与主代码包(如my_package)平级是最佳实践。这是 Python 社区的共识。 - 测试文件命名: 在
tests目录内的测试文件,通常遵循以下命名约定:test_<something>.py(例如:test_models.py,test_utils.py)<something>_test.py(例如:models_test.py,utils_test.py) - 这种形式不如test_前缀常见,但也被一些项目使用。pytest默认都能识别这两种。
__init__.py文件:- 在
tests目录下放一个空的__init__.py文件是常见的做法。这会将tests也视为一个 Python 包,有时有助于测试发现或处理相对导入(尤其是在旧项目或使用unittest时)。现代工具如pytest通常不需要它也能工作得很好。放或不放通常都不会有大问题,但放一个通常是安全的且符合惯例。
- 在
pytest是推荐工具: 使用pytest作为测试运行器和框架,它功能强大、灵活且对上述推荐的项目结构支持得非常好。- 测试运行命令:
- 在项目根目录运行
pytest即可自动发现并运行tests目录下所有符合命名规则的测试。 - 运行特定测试文件:
pytest tests/test_module1.py - 运行特定测试函数:
pytest tests/test_module1.py::test_specific_function
- 在项目根目录运行
🔧 总结
把你的测试代码放在项目根目录下的 tests 目录里(和你的主代码包文件夹并列)。 这是最清晰、最标准、最易于维护且最受工具支持的方式。✅
339



被折叠的 条评论
为什么被折叠?



