我有以下项目结构:
project/
├── src/
| ├── app_a/
│ │ ├── routes/
│ │ │ ├── get.py
│ │ │ └── post.py
│ │ └── app.py
| └── app_b/
│ ├── routes/
│ │ ├── get.py
│ │ └── post.py
│ └── app.py
└── test/
├── test_app_a.py
└── test_app_b.py
我通常像这样构建我的代码,其中我有一个单独的“src”和“test”目录,到目前为止我从未遇到过任何问题。但在这个项目中,我有多个具有相似结构的小应用程序。 app_a 和 app_b 中的“app.py”模块都从包路由(get.py 和 post.py)导入模块。这些小型应用程序在其容器中运行得很好,并且运行时一切都很好。但现在我想用 pytest 添加一些测试。
我在 proproject.toml 的 pythonpath 字段下添加了两个应用程序目录,如下所示:
[tool.pytest.ini_options]
pythonpath = [".", "src/app_a", "src/app_b"]
现在测试运行良好,但是测试 app_b 的 app.py 正在从 app_a 导入 get.py 和 post.py,这一点很清楚,因为 app_a 的路径位于 app_b 的路径之前。我想我完全理解为什么会发生这种情况,但我不知道如何解决这个问题!
你们中的一些很棒的Python专家可以帮我解决这个问题吗?
更新:没有必要在不同应用程序之间交叉导入。
最佳答案
解决方案:从项目目录运行测试,并且不要向路径添加任何内容。
像这样:
cd project
pytest test
然后您必须执行相对于该项目目录的导入,例如在 test_app_a.py
中:
import src.app_a.routes.get as get_a
def test_get_a():
get_a.function_in_get_dot_py()
如果您在 app.py
中有诸如 import paths.get
之类的内容来将其更改为
from .routes import get
用这个方法。
另请注意,现在您无法再运行 python src/app_a/app.py
但必须运行
python -m src.app_a.app
作为模块运行。
您可能需要将 __init__.py
文件添加到 src
或 app_a
文件夹才能使其正常工作。
如果应用程序需要相互导入,例如,如果 app_b 执行类似 from app_a...
的导入,则有一些解决方案。
- 应用程序可以更改为从同一目录(
src.app_a...
)引用,并在使用-m
单独运行时从该目录运行旗帜
python -m src.app_a.app
- 相对于 .py 文件的相对导入也可以工作,例如在
app_a/routes/get.py
中,您可以使用from ...app_b import
。仅当使用python -m ..
运行时才有效
- 将
src
添加到路径。
想法:
- 我确信还有其他解决方案可以做一些完全不同的事情,Python 导入系统当然有一个学习曲线。
- 最初我认为您可以在不将应用程序更改为模块并像这样运行它的情况下完成此操作,也许有一种方法,但至少这应该可行。
- 如果路径是全局的,则将其添加到路径中会很困惑,但这不是这里发生的情况。一般来说,如果可能的话,我会尽量避免改变路径。
- 拥有单独的 src 和测试文件夹非常好。
- 在我的项目中,只需
导入 src
然后执行例如src.py_file_there.function()
但由于某种原因,在此处测试时它不起作用。
关于python - pytest 具有相似包和模块结构的多个应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76194286/