如何使用子文件夹在 Python 中组织用于单元测试的测试文件

How to organise test files for unit testing in Python with sub folders

我想知道如何设置我的目录结构以允许从 tests 目录中的 project 导入任何 python 文件来测试它?

目前,当我尝试从 some_file_tests.py 中的 some_file.py 导入 class 时,我遇到了找不到模块的错误。

Traceback (most recent call last):
  File "e:\Documents\GitHub\Project\tests\util\some_file_test.py", line 3, in <module>
    from project.util.some_file import SomeFile
ModuleNotFoundError: No module named 'project'

tests/util.some_file_test.py

from project.util.some_file import SomeClass

这是目录结构

Project
 ┣ project
 ┃ ┣ util
 ┃ ┃ ┣ some_file.py
 ┃ ┃ ┗ __init__.py
 ┃ ┗ __init__.py
 ┣ tests
 ┃ ┣ util
 ┃ ┃ ┗ some_file_test.py

这里是 __init__.py 文件包含内容的示例。

project/__init__.py

from . import util

project/util/__init__.py

from . import some_file

两种方式

  1. 在 运行 测试之前将 project 路径添加到 PYTHONPATH 环境变量。
  2. 在项目中导入模块之前,在测试文件中以编程方式将 project 路径添加到 sys.path
import sys
sys.path.append("path/to/project")
from project.util.some_file import SomeClass

所以经过一些研究(感谢@gftea)我发现在每个 __init__ 文件中,做 from . import ___ 是不必要的并且可以删除(无论如何对于我的用例)。

然后我在根文件夹中创建了这些文件:

setup.py

from setuptools import setup
setup()

setup.cfg

[metadata]
name = <NAME>
version = 0.0.1
description = <DESCRIPTION>
long_description = file: README.md
long_description_content_type = text/markdown
url = <GITHUB REPOSITORY URL>
author = <AUTHOR(S)>
license = GPL-3.0
license_file = LICENSE
classifiers =
    License :: OSI Approved :: GNU General Public License v3 (GPLv3)
    Programming Language :: Python :: 3
    Programming Language :: Python :: 3 :: Only
    Programming Language :: Python :: 3.8
    Programming Language :: Python :: 3.9
    Programming Language :: Python :: 3.10

[options]
packages = find:
install_requires =
    python-dotenv==0.19.2
    requests==2.27.1
python_requires = >=3.8
tests_require =
    pytest
    coverage

[options.packages.find]
exclude =
    tests*

[options.extras_require]
dev =
    black==22.1.0
    pylint==2.12.2

之后我使用 pip install -e .

安装了我的包

然后在测试python文件中我可以做到from project.util.some_file import SomeClass